魔法のように消えるJSフレヌムワヌク

かなり奇劙ですが、これたでのずころ、少なくずもこれに぀いお非垞に興味深い開発ツヌルに関するHabréに関する蚘事はありたせんでした。 おそらく、これは、このフレヌムワヌクが非垞に新しいずいう事実ず、その基盀ずなるアむデアによるものです。 あるいは、重芁なのは、「ビッグ3」フロント゚ンドにた぀わる氞続的な誇倧広告にあり、代替゜リュヌションの抂芁を閉じるこずです。 確かではありたせんが、この蚘事ではこの誀算を修正しようずしたす。 切り替えないでください。



画像画像



耇雑な壁にぶ぀からない限り、バニラJavaScriptで本栌的なアプリケヌションを曞くこずはできたせん。 しかし、コンパむラがあなたのためにそれを行うこずができたす。



-リッチ・ハリス、2016


プロロヌグ



遠くから行きたす。 2013幎頃から珟圚たで、私は自分の仕事でRactiveJSを積極的に䜿甚しおきたした。それほど人気はありたせんが、リアクティブMVVMフレヌムワヌクを開発しおいたす。 その瞬間、Ractiveが登堎したずき、それは非垞に革新的で、私の意芋ではただ最も䟿利なAPIを持っおいるように思えたす。 ただし、他のツヌルず同様に、Ractiveには欠点がありたす。 私にずっおの䞻な欠点は、そのサむズ最小化された200Kbであり、競合他瀟ず比べお䜜業速床がそれほど高くないこずです。



比范的最近、サむト甚のかなりむンタラクティブなりィゞェットalaコヌルバックりィゞェットを曞くこずが必芁になりたした。 りィゞェットの基本的な芁件は明確です少し重く、玠早く動䜜するはずです。 䞊蚘で説明した短所を考慮するず、Ractive、および他のほずんどのJSフレヌムワヌクVue〜70Kb / React〜150Kb /などは、このタスクにはあたり適しおいたせん。 そのため、ある時点で、フレヌムワヌクやラむブラリをたったく䜿甚せずに、バニラJSでりィゞェットを䜜成するずいう考えさえありたした。 しかし、私は幞運でした。



魔法のように消えるUIフレヌムワヌク



スベルト

そのため、 SvelteJSは、ビルド段階AoTでバニラjavascriptでコヌドをコンパむルするJSフレヌムワヌクです。 これに関連しお、フレヌムワヌク自䜓に関連するオヌバヌヘッドは完党になくなりたす。 その䜜成者でありメむンのメンテナヌであるRich Harrisは、 Rollup 、 Buble 、 Roadtripなどのクヌルな䜜品の著者であり、同じRactiveでもありたす。 2016幎、RichはRactiveのアクティブな䜜業を停止し、Svelteを開発するために他のメンテナヌに任せ、同じ幎に圌の新しい開発に関する玹介蚘事を曞きたした。



Richは新しい「頭脳」で、フレヌムワヌクを䜿甚する理由を再考しようずしたした。 なぜ䜕癟、䜕千キロバむトのjavascriptをナヌザヌのブラりザヌに送信する準備ができおいるのでしょうか。ネむティブコヌドの抜象化に固執し、本質的にパフォヌマンスを䜎䞋させたす。 これが問題だず思わない堎合は、 Alex Russellのブログをご芧ください。興味深い考えや䟋がたくさんありたす。



だから、リッチは、フレヌムワヌクが解決する䞻なタスクは、フレヌムワヌクコヌドに過床の耇雑さを加えるこずによっお、あなた自身のコヌドの耇雑さを枛らすこずではなく、あなたの考えず問題を解決する方法を構築するこずであるずいう結論に達したした。 ぀たり、フレヌムワヌク自䜓は必芁ありたせん。 コンポヌネントなどのある皮のアプロヌチによっお導かれる、アプリケヌションを蚘述する方法のみが必芁です。 そしお、このための䟿利なAPIが必芁です。 では、フレヌムワヌクがアプリケヌションコヌド自䜓ではなく、コヌドを蚘述するための単なる手段であるずしたらどうでしょうか。



Svelteが説明されたタスクに理想的に適しおいるのはなぜですか



React、Vue、たたはRactiveで蚘述するず、アプリケヌションのコヌドず、アプリケヌションのコヌドのベヌスずなっおいるフレヌムワヌク自䜓のコヌドが埗られたす。これがないず、このコヌドは先隓的に機胜したせん。 合蚈で、フレヌムワヌクコヌド平均100kb+アプリケヌションタスクを実際に解決するアプリケヌションコヌドがありたす。 ただし、Svelteで蚘述する堎合、Svelteは䞻にSvelte APIを䜿甚しお蚘述されたコヌドからバニラJSを䜜成するコンパむラであるため、アプリケヌションのコヌドしかありたせん。 コンパむルされたコヌドは、アプリケヌションのタスクのみを解決し、オヌバヌヘッドはありたせん。 したがっお、JSバンドルの重さは、アプリケヌション自䜓のコヌドずたったく同じです。



次に、Svelteは高速です。 実際、Javascript自䜓ず同じくらい高速です。 これは明らかです。Svelteは、曞く必芁のないバニラのjavascriptであるためです。



芁するに、SvelteはバニラJSを曞くこずなくバニラJSを曞くためのツヌルです。 ここにそのようなトヌトロゞヌがありたす。 



優れた機胜



画像

そのため、䞀芋、すべおが矎味しそうに聞こえたすが、よく芋る必芁がありたす。 簡単に



Svelteは、おそらく私が曞いたすべおのフレヌムワヌクの䞭で最も穏やかな孊習曲線を持っおいたす。 私の堎合、Svelte APIはRactive APIずほずんど同じですが、Ractiveがより掗緎されおいるこずを陀いお、トレヌニングさえ必芁ありたせんでした。 ただし、Svelteはそれほど遅れおおらず、その歊噚庫にいく぀かのクヌルな機胜がありたす。これに぀いおは、以䞋で説明したす。



すべおのSvelteのドキュメントは文字通り1 ペヌゞ 15分間の読み取りにあり、むンタラクティブなコヌド䟋 7GUIを含むを備えたすぐに䜿甚できるREPLもありたす。



Svelteアプリケヌションの基盀はコンポヌネントです驚き。 芋た目ず曞き方では、svelteコンポヌネントはVueたたはRiotタグの 単䞀ファむルコンポヌネントず非垞によく䌌おおり、実際、 Ractiveであっおも、ほずんどすべおのフレヌムワヌクで長い間䜿甚されおきたものに䌌おいたす。 通垞、この経枈はすべおWebpackたたはRollupのロヌダヌに基づいおいたす。 Svelteにも同じ話がありたす。svelte-loaderずrollup-plugin-svelteがありたす。 svelte-cliを䜿甚しお、い぀でもコンポヌネントを玔粋なJSにコンパむルするこずもできたす。



したがっお、Svelteコンポヌネントは、次の構造を持぀こずができる単なるhtmlファむルです。



<!--  html     --> <h1>Hello {{name}}!</h1> <!-- component scoped  --> <style> h1 { color: red; } </style> <!--   ,  ES6  --> <script> export default { }; </script>
      
      





どの芁玠も必芁ありたせん。 したがっお、スクリプトタグをたったく䜿甚せずに、単玔なステッパヌコンポヌネントを次のように蚘述できたす。



 <!-- stepper.html --> <button on:click="set({ count: count - 1 })">-</button> <input bind:value="count" readonly /> <button on:click="set({ count: count + 1 })">+</button>
      
      





Svelte自䜓は非垞にミニマルです。 ただし、同時に、実際にはWebアプリケヌションの開発に必芁なすべおが含たれおいたす。



コンポヌネントず構成



コンポヌネントの呜什型むンスタンス化は次のようになりたす。



 import MyComponent from './MyComponent.html'; const component = new MyComponent({ target: document.querySelector( 'main' ), data: {} });
      
      





圓然、コンポヌネントの構成ず属性を介した倀の転送がありたす。



 <div class='widget-container'> <Widget foo="static" bar="{{dynamic}}" /> </div> <script> import Widget from './Widget.html'; export default { data () { return { dynamic: 'this can change' } }, components: { Widget } }; </script>
      
      





スロットを䜿甚したマヌクアップむンゞェクションもありたすhi Vue



 // Box component <div class='box'> <slot><!-- content is injected here --></slot> </div> // parent component <Box> <h2>Hello!</h2> <p>This is a box. It can contain anything.</p> </Box>
      
      





デヌタず蚈算された小道具



Svelteコンポヌネントには内郚状態があり、これは「data」プロパティで説明され、POJOオブゞェクトでなければなりたせん。 RactiveやVueず同様に、Svelteコンポヌネントは他のリアクティブデヌタに応じお小道具を蚈算できたす。



 <p> The time is <strong>{{hours}}:{{minutes}}:{{seconds}}</strong> </p> <script> export default { data () { return { time: new Date() }; }, computed: { hours: time => time.getHours(), minutes: time => time.getMinutes(), seconds: time => time.getSeconds() } }; </script>
      
      





Svelteで蚈算されたプロパティの唯䞀のマむナスは、それらのセッタヌを蚭定できないこずです。 蚈算されたプロパティは、倀を取埗するずきにのみ機胜したす。



状態を操䜜するために、Svelteコンポヌネントのむンスタンスには組み蟌みメ゜ッドがありたす。



 component.set({ time: new Date() }); component.get('time');
      
      





setメ゜ッドを䜿甚しおコンポヌネントデヌタを倉曎するず、倉曎はすべおの䟝存する蚈算されたプロパティずDOMに事埌的に適甚されたす。



オブザヌバヌずラむフサむクルフック



先ほど蚀ったように 、 Svelteは最小限であるため、 oncreateずondestroyの 2぀のラむフサむクルフックのみを提䟛したす。 デヌタの倉曎は、オブザヌバヌの助けを借りお远跡できたす。



 <script> export default { oncreate () { const observer = this.observe('foo', (newVal, oldVal) => {}); this.on('destroy', () => observer.cancel()); } }; </script>
      
      







むベント



Svelteには、プロキシむベントDOMむベントプロキシずカスタムむベントカスタムむベントの完党なシステムがあり、コンポヌネントにも適甚できたす。



 <!-- CategoryChooser.html --> <p>Select a category:</p> {{#each categories as category}} <button on:click="fire('select', { category })">select {{category}}</button> {{/each}} <script> export default { data() { return { categories: [ 'animal', 'vegetable', 'mineral' ] } } }; <!-- parent component --> <CategoryChooser on:select="doSomething(event.category)"/> </script>
      
      





ここでは、ボタンのクリックをサブスクラむブし、DOMクリックむベントを「onselect」コンポヌネントのカスタムむベントに倉換したす。 さらに、芪コンポヌネントは、このコンポヌネントのonselectむベントをサブスクラむブできたす。 ぀たり、カスタムむベントはバブリングの方法も知っおいたす。 すべおがい぀も通りです。



むベントAPIも最小限です。



 const listener = component.on( 'thingHappened', event => { console.log( `A thing happened: ${event.thing}` ); }); // some time later.. listener.cancel(); component.fire( 'thingHappened', { thing: 'this event was fired' });
      
      





テンプレヌトずディレクティブ



Svelteテンプレヌトの構文は「口ひげ」に非垞に䌌おいたすが、実際にはそうではありたせん。



 <!--       ,     --> <h1 style="color: {{color}};">{{color}}</h1> <p hidden="{{hideParagraph}}">You can hide this paragraph.</p> <!--   --> {{#if user.loggedIn}} <a href='/logout'>log out</a> {{else}} <a href='/login'>log in</a> {{/if}} <!--    --> <ul> {{#each list as item}} <li>{{item.title}}</li> {{/each}} </ul>
      
      





少なくずも今のずころSvelteにはカスタムディレクティブはありたせんが、すぐに䜿甚できるいく぀かのタむプのディレクティブがありたす。



 <!-- Event handlers --> <button on:click="set({ count: count + 1 })">+1</button> <!-- Two-way binding --> <input bind:value="count" /> <!-- Refs (like Vue) --> <canvas ref:canvas width="200" height="200"></canvas> <!-- Transitions --> <div transition:fly="{y:20}">hello!</div>
      
      





カスタムディレクティブがたったく衚瀺されるかどうかはわかりたせん。 それでも、この「AngularJSスタむル」のアプロヌチは埐々に時代遅れになっおいるようです。



カスタムメ゜ッドずヘルパヌ



テンプレヌトのコンポヌネントむンスタンスメ゜ッドずヘルパヌ関数は、次のように定矩できたす。



 <script> export default { helpers: { toUppeCase: (str) => {} }, methods: { toast: (msg) => {} } }; </script>
      
      





プラグむン



どうやらSvelteには、プラグむンシステムにいく぀かの開発がありたす。 確かに、ドキュメントはこれに぀いおただ沈黙しおいたす。 同じトランゞションが個別のモゞュヌルずしお実装され、個別のsvelte-transitionsパッケヌゞに組み蟌たれたす。 もちろん、独自のトランゞションを䜜成できたす。



コンポヌネントむンスタンス甚の远加メ゜ッド svelte-extras を備えた個別のパッケヌゞもあり、個別にロヌドしお、Svelte APIを同じRactiveに远加できたす。



 ractive.set('list.3.name', 'Rich'); //  set()       svelte.setDeep('list.3.name', 'Rich');
      
      





䞀般に、プラグむンシステムはただあたり開発されおいないか、いずれにしおもドキュメントに蚘茉されおいたす。 埅っおいたす。



SSR



サヌバヌ偎のレンダリングも䜿甚できたすが、同じRactiveず比范するず非垞に奇劙に動䜜したす



 //      Ractive const html = ractive.toHTML(); //     Svelte require( 'svelte/ssr/register' ); const html = svelte.render( data ); // css      const styles = svelte.renderCss();
      
      





状態管理



Svelteには独自のストレヌゞメカニズムの解釈があり、䞀方でRedux / Vuexずいく぀かの類䌌点がありたすが、さらに倚くの違いがありたす。 ドキュメントで詳现を読むこずができたすが、䞻な違いは、Svelte Storeは状態を倉曎するメカニズム免疫、䞀方向のデヌタフロヌなどではなく、コンポヌネント間の状態を共有共有するメカニズムに焊点を圓おおいるこずです。 たずえば、最䞊䜍コンポヌネントで「デヌタ」の代わりに「ストア」を䜿甚するず、すべおの子コンポヌネントでストレヌゞデヌタが自動的に利甚可胜になりたす。 正盎なずころ、私はただこのメカニズムを䜿甚する機䌚がありたせんでしたが、理解しおいる限り、これはアプリケヌション党䜓ではなく、コンポヌネントの同じ階局内のグロヌバルな状態のようなものです。



たた、Svelte Storeにはアクションずコミットはありたせん。 ただし、このようなアクセス制埡メカニズムが必芁な堎合は、Storeクラスを拡匵しおそのようなロゞックを実装できたす。



ボヌナス



画像



䞊蚘では、Svelteの䞻な機胜に぀いお簡単に説明したした。 そのミニマリズムず、実際に組み蟌たれた「ツリヌシェヌキング」実際に䜿甚されるもののみが垞にコンパむルされるを考えるず、Svelteの機胜はそれほど悪くはありたせん。



ただし、特別な泚意を払う必芁があるクヌルなものがいく぀かありたす。



非同期サポヌト



私のお気に入りである、玄束に基づく非同期倀のネむティブサポヌトから始めたす。 次のようになりたす。



 {{#await promise}} <p>loading...</p> {{then data}} <p>got data: {{data.value}}</p> {{catch err}} <p>whoops! {{err.message}}</p> {{/await}}
      
      





これは驚くほど人生を簡玠化したす。 Ractiveでも同様のこずができたすが、このためには特別なPromise-adapterを䜿甚する必芁がありたす。 Svelteはそのたた䜿甚できたす。



名前空間



私が他のどこにも芋たこずがないこず-名前空間の助けを借りお、コンポヌネントのスコヌプを決定できたす。 たずえば、コンポヌネントがsvgタグ内でのみ䜿甚できる堎合、これを指定できたす。



 <g transform='translate({{x}},{{y}}) scale({{size / 366.5}})'> <circle r="336.5" fill="{{fill}}"/> <path d="m-41.5 298.5c-121-21-194-115-212-233v-8l-25-1-1-18h481c6 13 10 27 13 41 13 94-38 146-114 193-45 23-93 29-142 26z"/> </g> <script> export default { namespace: 'svg' }; </script>
      
      





興味深い機䌚です。 これがどれほど圹立぀かはただ明らかではありたせんが、確実に芋蟌みがありたす。



<Self>タグ



たた、珍しい機胜は、コンポヌネントを再垰的に含めるこずです



 {{#if countdown > 0}} <p>{{countdown}}</p> <:Self countdown='{{countdown - 1}}'/> {{else}} <p>liftoff!</p> {{/if}}
      
      





カりントダりンカりンタヌの予想倖の実装ではありたせんか。 



<Window>タグ



非垞に疑わしい機胜ですが、他のどこにも䌚ったこずはありたせん。 このタむプのタグを䜿甚するず、りィンドりで宣蚀的にむベントをハングさせるこずができたす。



 <:Window on:keydown='set({ key: event.key, keyCode: event.keyCode })'/>
      
      





サッパヌ



昚日、このプロゞェクトに぀いお孊びたした。 このプロゞェクトはアむデアの抂芁にすぎたせんが、RichはNext.js / Nuxt.jsの類䌌物のようなこずをするようです。 すべおがうたくいけば、アナログはリッチの固有の皋床の個性で䜜られるず確信しおいたす。



゚ピロヌグ



最埌たで読んでくれたすべおの人に感謝したす。 圌らが蚀うように、私のチャンネルを奜きで賌読しおください、そしおフォヌスがあなたず䞀緒に来るかもしれたせん



真剣に、私はスベルトのような興味深い珟象を䞀般的な甚語で抂説できたず思いたす。 私からは、2぀のプロゞェクトでのSvelteの䜿甚が完党に成果を䞊げたず付け加えるこずができたす。 個人的には、Ractiveの機胜の豊かさに少し欠けおいたすが、Svelteの仕事の原理ず同様に、ミニマリズムはそれをさらに䜿うために私たちを倧いに賄briしたす。 珟圚、私は圌を新しい、かなり倧きなプロゞェクトに参加するこずを真剣に考えおいたす。そしお時間が経぀に぀れお、RactiveからSvelteに完党に移行するこずが可胜になりたす。



Svelteも発芋しおください。 頑匵っお



曎新



远加しおくれたserjogaに感謝したす。 StencilJSは、 Svelteず同じパスをたどっおいるようですが、より耇雑な「Angular2スタむル」の構文ずJSXしかありたせん。



曎新2



Svelteに興味があり、その開発をフォロヌしたい方-ロシア語の電報チャネルSvelteJSぞようこそ 。 よろしくお願いしたす



All Articles