Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Type-safe front-end development using Rust/Rustを使った型安全なフロントエンド開発

tipo159
December 08, 2023

Type-safe front-end development using Rust/Rustを使った型安全なフロントエンド開発

Objective:
Introducing type-safe front-end development using Rust, now a reality

Composition:

TypeScript is not type-safe
Problems with type-safe AltJS
Concerns of front-end development using Rust(WASM)

Knowledge of JavaScript frameworks cannot be appropriated
Overhead of data conversion between WASM and JavaScript (UTF-8 and UTF-16, etc.)
Increase in data size due to WASM
Increase in memory used at runtime due to WASM

tipo159

December 08, 2023
Tweet

More Decks by tipo159

Other Decks in Programming

Transcript

  1. ϓϨθϯͷ໨తͱߏ੒ w ໨త w 3VTUΛ࢖ͬͨܕ҆શͳϑϩϯτΤϯυ։ൃ͕ɺݱ࣮తʹͳͬͨ͜ͱΛ঺հ w ߏ੒ w 5ZQF4DSJQU͸ܕ҆શͰ͸ͳ͍ w

    ܕ҆શͳ"MU+4ͷ໰୊఺ w 3VTU 8"4. Λ࢖ͬͨϑϩϯτΤϯυ։ൃͷݒ೦఺ w 3VTU༻ϑϩϯτΤϯυϑϨʔϜϫʔΫ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ݁Ռ
  2. ܕ҆શͳ"MU+4ͷ໰୊఺  w ܕ҆શͳ"MU+4͸ؔ਺ܕ͕ଟ͍ͨΊɺ+BWB4DSJQU͔Βͷ৐Γ׵͕͑ࠔ೉ w 3FBTPO.- 1VSF4DSJQU &MN 3F4DSJQU w

    ϑϩϯτΤϯυϑϨʔϜϫʔΫͷબ୒ʹ੍ݶ ݴޠ 3FBDU W 7VF W "OHVMBS W 4PMJE+4 W 3FBTPO.- W W 7  1VSF4DSJQU W 7 7 7 &MN 7 7 7  3F4DSJQU 7   7
  3. ܕ҆શͳ"MU+4ͷ໰୊఺  w ֤ݴޠͷ։ൃ͕௿ௐ ݴޠ (JU)VC4UBS (JU)VC "DUJWFQVMMSFRVFTUT NPOUI (JU)VC

    "DUJWFJTTVFTNPOUI 5ZQF4DSJQU L   3FBTPO.- L   1VSF4DSJQU L   &MN L   3F4DSJQU L   3VTU L  
  4. 3VTU 8"4. Λ࢖ͬͨϑϩϯτΤϯυ։ൃͷݒ೦఺ w +BWB4DSJQU༻ϑϨʔϜϫʔΫͷ஌ࣝΛྲྀ༻Ͱ͖ͳ͍ w +BWB4DSJQU༻ϑϨʔϜϫʔΫʹΠϯεύΠϠ͞Εͨ3VTU༻ϑϨʔϜϫʔΫ͕ଘࡏ w 8"4.ͱ+BWB4DSJQUͷσʔλม׵ 65'ͱ65'ͳͲ

    ͷΦʔόϔου w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ%VSBUJPOͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫΑΓ଎͍ 3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔσʔλαΠζͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ4UBSUVQNFUSJDTͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓૣ͍3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔ࣮ߦ࣌ʹ࢖༻͢ΔϝϞϦͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ.FNPSZBMMPDBUJPOͰɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓ3VTU༻ϑϨʔϜϫʔΫͷํ͕࢖༻ϝϞϦ͕େ͖͍͜ͱΛ֬ೝɺվળ͕ඞཁ
  5. 3VTU༻ϑϩϯτΤϯυϑϨʔϜϫʔΫ ϑϨʔϜϫʔΫ όʔδϣϯ ԿʹΠϯεύΠϠ͞Ε͔ͨ උߟ -FQUPT 7 4PMJE+4 Ծ૝%0.ෆ࢖༻ 4FSWFS4JEF3FOEFSJOH

    443 ͚ͩͰͳ ͘ɺ)ZESBUJPO΋αϙʔτ 4ZDBNPSF 7 4PMJE+4 Ծ૝%0.ෆ࢖༻ 443͚ͩͰͳ͘ɺ)ZESBUJPO΋αϙʔτ :FX 7 3FBDU Ծ૝%0.࢖༻ 443͚ͩͰͳ͘ɺ)ZESBUJPO΋αϙʔτ %JPYVT 7 3FBDU Ծ૝%0.࢖༻  TVCUSFFNFNPSJ[BUJPO EJPYVTXFC$MJFOU4JEF3FOEFSJOH EJPYVTMJWFWJFX443 EJPYVTGVMMTUBDL443 )ZESBUJPO *DFE 7 5IF&MN"SDIJUFDUVSF 4UBUF .FTTBHFT 7JFXMPHJD 6QEBUFMPHJD &MNͰ͸.PEFM 7JFX 6QEBUF JDFE@XFC͸FYQFSJNFOUBM
  6. 3VTU༻ϑϩϯτΤϯυϑϨʔϜϫʔΫͷΞΫςΟϏςΟ ϑϨʔϜϫʔΫ (JU)VC4UBS (JU)VC "DUJWFQVMMSFRVFTUT NPOUI (JU)VC "DUJWFJTTVFTNPOUI -FQUPT L

      4ZDBNPSF L   :FX L   %JPYVT L   *DFE L   4PMJE+4 L   3FBDU L   7VF L   "OHVMBS L  
  7. 4PMJE+4 +BWB4DSJQU ͷهड़ྫ import { createSignal } from "solid-js"; export

    default function Counter() { const [count, setCount] = createSignal(0); return ( <button onClick={() => setCount(count() + 1)}> Clicks: {count()} </button> ); }
  8. -FQUPT 3VTU ͷهड़ྫ use leptos::*; #[component] pub fn Counter() ->

    impl IntoView { let (count, set_count) = create_signal(0); view! { <button on:click=move |_| set_count.update(|count| *count += 1)> ”Clicks: " {count} // = {move || count.get()} </button> } } pub fn main() { mount_to_body(|| view! { <Counter/> }) }
  9. 3VTU 8"4. Λ࢖ͬͨϑϩϯτΤϯυ։ൃͷݒ೦఺ w +BWB4DSJQU༻ϑϨʔϜϫʔΫͷ஌ࣝΛྲྀ༻Ͱ͖ͳ͍ w +BWB4DSJQU༻ϑϨʔϜϫʔΫʹΠϯεύΠϠ͞Εͨ3VTU༻ϑϨʔϜϫʔΫ͕ଘࡏ w 8"4.ͱ+BWB4DSJQUͷσʔλม׵ 65'ͱ65'ͳͲ

    ͷΦʔόϔου w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ%VSBUJPOͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫΑΓ଎͍ 3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔσʔλαΠζͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ4UBSUVQNFUSJDTͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓૣ͍3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔ࣮ߦ࣌ʹ࢖༻͢ΔϝϞϦͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ.FNPSZBMMPDBUJPOͰɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓ3VTU༻ϑϨʔϜϫʔΫͷํ͕࢖༻ϝϞϦ͕େ͖͍͜ͱΛ֬ೝɺվળ͕ඞཁ
  10. +TXFCGSBNFXPSLTCFODINBSL$ISPNF %VSBUJPOJONJMMJTFDPOET /BNF 4PMJE+4 %JPYVT -FQUPT 7VF 4ZDBNPSF "OHVMBS &MN

    3FBDU :FX DSFBUFSPXT          SFQMBDFBMMSPXT          QBSUJBMVQEBUF          TFMFDUSPX          TXBQSPXT          SFNPWFSPX          DSFBUFNBOZSPXT           BQQFOESPXTUPMBSHFUBCMF          DMFBSSPXT          XFJHIUFEHFPNFUSJDNFBO         
  11. 3VTU 8"4. Λ࢖ͬͨϑϩϯτΤϯυ։ൃͷݒ೦఺ w +BWB4DSJQU༻ϑϨʔϜϫʔΫͷ஌ࣝΛྲྀ༻Ͱ͖ͳ͍ w +BWB4DSJQU༻ϑϨʔϜϫʔΫʹΠϯεύΠϠ͞Εͨ3VTU༻ϑϨʔϜϫʔΫ͕ଘࡏ w 8"4.ͱ+BWB4DSJQUͷσʔλม׵ 65'ͱ65'ͳͲ

    ͷΦʔόϔου w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ%VSBUJPOͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫΑΓ଎͍ 3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔσʔλαΠζͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ4UBSUVQNFUSJDTͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓૣ͍3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔ࣮ߦ࣌ʹ࢖༻͢ΔϝϞϦͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ.FNPSZBMMPDBUJPOͰɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓ3VTU༻ϑϨʔϜϫʔΫͷํ͕࢖༻ϝϞϦ͕େ͖͍͜ͱΛ֬ೝɺվળ͕ඞཁ
  12. +TXFCGSBNFXPSLTCFODINBSL$ISPNF 4UBSUVQNFUSJDT MJHIUIPVTFXJUINPCJMFTJNVMBUJPO /BNF 4PMJE+4 %JPYVT -FQUPT 7VF 4ZDBN PSF

    "OHVMB S &MN 3FBDU :FX DPOTJTUFOUMZJOUFSBDUJWF                   UPUBMLJMPCZUFXFJHIU          HFPNFUSJDNFBO         
  13. 3VTU 8"4. Λ࢖ͬͨϑϩϯτΤϯυ։ൃͷݒ೦఺ w +BWB4DSJQU༻ϑϨʔϜϫʔΫͷ஌ࣝΛྲྀ༻Ͱ͖ͳ͍ w +BWB4DSJQU༻ϑϨʔϜϫʔΫʹΠϯεύΠϠ͞Εͨ3VTU༻ϑϨʔϜϫʔΫ͕ଘࡏ w 8"4.ͱ+BWB4DSJQUͷσʔλม׵ 65'ͱ65'ͳͲ

    ͷΦʔόϔου w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ%VSBUJPOͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫΑΓ଎͍ 3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔσʔλαΠζͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ4UBSUVQNFUSJDTͰ͸ɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓૣ͍3VTU༻ϑϨʔΫϫʔΫ͕ଘࡏ w 8"4.ԽʹΑΔ࣮ߦ࣌ʹ࢖༻͢ΔϝϞϦͷ૿େ w +TXFCGSBNFXPSLTCFODINBSL$ISPNFͷ.FNPSZBMMPDBUJPOͰɺ+BWB4DSJQU༻ϑϨʔϜϫʔΫ ΑΓ3VTU༻ϑϨʔϜϫʔΫͷํ͕࢖༻ϝϞϦ͕େ͖͍͜ͱΛ֬ೝɺվળ͕ඞཁ
  14. +TXFCGSBNFXPSLTCFODINBSL$ISPNF .FNPSZBMMPDBUJPOJO.#T /BNF 4PMJE+4 %JPYVT -FQUPT 7VF 4ZDBNP SF "OHVMBS

    &MN 3FBDU :FX SFBEZNFNPSZ          SVONFNPSZ          VQEBUFFWFSZUISPXGPSL SPXT          DSFBUJOHDMFBSJOHLSPXT          SVONFNPSZL          HFPNFUSJDNFBO         
  15. 3VTUίʔυͷղઆ #[component] ← ҎԼͷؔ਺ʹίϯϙʔωϯτଐੑΛ෇༩͢Δଐੑ෩ϚΫϩ(Attribute-like macros) pub fn Counter() -> impl

    IntoView { ↑ IntoView τϨΠτ(Trait)Λ໭Γ஋ʹ͢ΔͨΊʹɺimpl IntoViewͱهड़ let (count, set_count) = create_signal(0); ↑ ଟ஋Λ୅ೖ͢ΔͨΊʹɺλϓϧ(Tuple)Λ࢖༻ view! { <button on:click=move |_| set_count.update(|count| *count += 1)> ↑ Ϋϩʔδϟ(Closure):؀ڥΛΩϟϓνϟͰ͖Δಗ໊ؔ਺ ↑ Ϋϩʔδϟͷ1ͭͷҾ਺Λ࢖༻͠ͳ͍ ↑ Ϋϩʔδϟ͸ɺ؀ڥͰ࢖༻͍ͯ͠Δ஋ͷॴ༗ݖΛڧ੍తʹୣ͏ .update()͸ɺγάφϧͷݱࡏ஋΁ͷมߋՄೳͳࢀরΛҾ਺ʹऔΔؔ਺ΛҾ਺ʹ औΓɺߋ৽͕ඞཁͳαϒεΫϥΠόʹ௨஌ ”Clicks: " {count} // = {move || count.get()} .get()͸ɺγάφϧͷݱࡏ஋ΛΫϩʔϯ͠ɺকདྷͷ஋ͷมԽΛ௥੻ </button> } }