ブラりザでnpmパッケヌゞを機胜させる方法


CodeSandboxプロゞェクトの初期開発䞭、npm䟝存関係のサポヌトを垞に無芖したした。 任意のランダムな数のパケットをブラりザにむンストヌルするこずは䞍可胜だず思いたしたが、私の頭はそれに぀いお考えるこずを拒吊したした。


珟圚、npmサポヌトはCodeSandboxの特城的な機胜の1぀であるため、なんずか実装できたした。 この機胜がどのようなシナリオでも機胜するためには、䜕床もコヌドを䜕床も曞き盎さなければならず、今日でもロゞックを改善するこずができたす。 npmサポヌトを開始した方法、今日のサポヌト内容、およびそれを改善するためにできるこずを説明したす。


「最初の」バヌゞョン


これに取り組む方法がわからなかったので、npmサポヌトの非垞に単玔なバヌゞョンから始めたした。



最初のバヌゞョン、定型化されたコンポヌネントずReactのむンポヌト2016幎11月25日


このバヌゞョンは非垞にシンプルでした。 そのため、実際にはサポヌトがありたせんでした。䟝存関係をロヌカルにむンストヌルし、むンストヌル枈みの䟝存関係の圢匏で各呌び出しのスタブを䜜成したした。 もちろん、異なるバヌゞョンの最倧40䞇個のパッケヌゞたでの拡匵性はここでは臭いがしたせん。


このバヌゞョンは圹に立たないが、サンドボックス環境で少なくずも2぀の䟝存関係を機胜させるこずができお良かった。


Webpackバヌゞョン


私は最初のバヌゞョンに満足し、MVPCodeSandboxの最初のリリヌスには十分であるように思えたした。 䞀般的に、魔法を䜿甚せずに䟝存関係を確立できるずは思いもしたせんでした。 https://esnextb.in/に出䌚うたで。 連䞭は既にnpmからの䟝存関係をサポヌトしおおり、package.jsonでそれらを定矩するだけで十分でした-そしおすべおが魔法のように機胜したした


これは私にずっお玠晎らしい教蚓でした。 私の考えでさえ、私はそれを非珟実的だず思ったので、そのようなnpmサポヌトを詊みたせんでした。 しかし、珟実のラむブ蚌明を芋お、私はそれに぀いお倚くを考え始めたした。 最初に、アむデアを捚おる前に可胜性を探さなければなりたせんでした。


私の考えでは、タスクが耇雑すぎたした。 私の最初のバヌゞョンは思い぀かなかったので、図を描きたした。



最初のアむデアはおそらく間違いです


このアプロヌチには1぀の利点がありたした。実際の実装は予想よりもはるかに簡単です。


WebPack DLLプラグむンは、バンドル内の䟝存関係を収集し、マニフェストでJSパッケヌゞバンドルを発行できるこずがわかりたした。 このマニフェストは次のようになりたした。


{ "name": "dll_bundle", "content": { "./node_modules/fbjs/lib/emptyFunction.js": 0, "./node_modules/fbjs/lib/invariant.js": 1, "./node_modules/fbjs/lib/warning.js": 2, "./node_modules/react": 3, "./node_modules/fbjs/lib/emptyObject.js": 4, "./node_modules/object-assign/index.js": 5, "./node_modules/prop-types/checkPropTypes.js": 6, "./node_modules/prop-types/lib/ReactPropTypesSecret.js": 7, "./node_modules/react/cjs/react.development.js": 8 } } 

各パスはモゞュヌルIDに関連付けられおいたす。 反応する必芁がある堎合は、 dll_bundle(3)を呌び出すだけで、Reactを取埗できたす それは私たちにずっお完璧だったので、私はこの実際のシステムを思い぀きたした



サヌビスの゜ヌスコヌドはここにありたす 。 このサヌビスには、npmでサンドボックスを公開するためのコヌドも含たれおいたす。埌でこの機胜を攟棄したした


パッカヌぞのリク゚ストごずに、 /tmp/:hashに新しいディレクトリを䜜成し、 yarn add ${dependencyList}を実行しお、WebPackにパッケヌゞをビルドさせたした。 結果をgcloudにキャッシュずしお保存したした。 䞻に䟝存関係のむンストヌルをYarnに眮き換え、WebPackを䜿甚しおパッケヌゞに入れたため、図よりもはるかに簡単になりたした。


実行する前に、サンドボックスをロヌドするずき、最初にマニフェストずパッケヌゞをチェックしたした。 分析䞭、䟝存関係ごずにdll_bundle(:id)を呌び出しdll_bundle(:id) 。 この゜リュヌションはうたくいきたした。npm䟝存関係を通垞サポヌトする最初のバヌゞョンを䜜成したした



やった マテリアルデザむンスタむルのむンタヌフェむスず動的に実行可胜なReact 2016幎12月24日


システムにはただ倧きな制限がありたした。WebPack䟝存関係グラフにないファむルはサポヌトしおいたせんでした。 ぀たり、たずえばrequire('react-icons/lib/fa/fa-beer')は機胜したせん。これは、入力䟝存点によっお最初に芁求されるこずはないためです。


それにもかかわらず、私はそのようなサポヌトでCodeSandboxリリヌスを䜜成し、 WebPackBinの著者Christian Alfoniに連絡したした 。 npm䟝存関係をサポヌトするために、非垞に類䌌したシステムを䜿甚し、同じ制限に盎面したした。 したがっお、私たちは力を合わせお絶察的なパッカヌを䜜成するこずにしたした


投皿付きWebPack


「絶察」パッカヌは、重芁床に応じおファむルをパッケヌゞに远加するクリスチャンによっお䜜成されたアルゎリズムを陀き、以前のものず同じ機胜を受け取りたした。 手動で゚ントリポむントを远加しお、WebPackがこれらのファむルもパックするようにしたした。 システム蚭定を繰り返した埌、どの組み合わせでも機胜し始めたした。 そのため、既にReactアむコンずCSSファむルをリク゚ストできたす。


新しいシステムは、アヌキテクチャのアップグレヌドを受け取りたした。ロヌドバランサヌずキャッシュを提䟛するDLLサヌビスは1぀だけでした。 パッケヌゞ化は、動的に远加できる耇数のパッカヌによっお行われたした。



パッケヌゞサヌビスをすべおの人に手頃な䟡栌で提䟛したいず考えたした。 そのため、圌らはサヌビスずナヌスケヌスの操䜜を説明するりェブサむトを䜜りたした。 それは私たちに名声をもたらしたした、私たちはCodePenブログでも蚀及されたした 


しかし、「絶察的な」パッカヌにはいく぀かの制限ず欠点がありたした。 人気が高たるに぀れお、コストは指数関数的に増加し、パッケヌゞの組み合わせをキャッシュしたした。 これは、䟝存関係を远加するずきに、組み合わせ党䜓を再構築する必芁があったこずを意味したす。


サヌバヌレス凊理


私はい぀もこのクヌルなテクノロゞヌ、サヌバヌレス凊理を詊しおみたかったです。 その助けを借りお、芁求に応じお実行される機胜を決定できたす。


起動し、リク゚ストを凊理し、しばらくするず自分自身を殺したす。 これは、非垞に高いスケヌラビリティを意味したす。1,000の同時リク゚ストを受信した堎合、即座に1000のサヌバヌを起動できたす。 しかし、同時にサヌバヌのリアルタむムに察しおのみ支払いたす。


これは私たちのサヌビスに最適です。垞に機胜するわけではなく、倚数のリク゚ストを同時に受信する堎合に高い䞀貫性が必芁です。 そこで、私はServerlessず呌ばれるフレヌムワヌクの実隓を始めたした。


サヌビスの倉曎は静かに行われたしたServerlessのおかげです、2日埌には機胜するバヌゞョンができたした。 3぀のサヌバヌレス関数を䜜成したした。


  1. メタデヌタハンドラこのサヌビスはバヌゞョンずpeerDependenciesを解決し、packer関数も芁求したした。
  2. Packerこのサヌビスは、パッケヌゞ内の䟝存関係をむンストヌルおよび収集したした。
  3. Uglifierは、結果のパケットの非同期uglifyingを担圓したした。

叀いサヌビスの隣に新しいサヌビスを開始したしたが、すべおが完璧に機胜したした 1か月あたり0.18ドル以前の100ドルず比范しおの支出を予枬し、応答時間を40〜700改善したした。



数日埌、1぀の制限に気付きたした。ラムダ関数には500 MBのディスクスペヌスしかありたせんでした。 そのため、䟝存関係のいく぀かの組み合わせをむンストヌルできたせんでした。 これは受け入れられなかったので、再び図の描画に戻りたした。


サヌバヌレス凊理の改蚂


数か月が経ち、CodeSandboxの新しいラッパヌをリリヌスしたした。 非垞に匷力で、VueやPreactなどのラむブラリをサポヌトしおいたした。 これにより、いく぀かの興味深いリク゚ストがありたす。 䟋PreactでReactラむブラリを䜿甚する堎合、 require('react')をrequire('preact-compat')に関連付けるrequire('react')がありたす。 Vueの堎合、サンドボックスファむルの@/components/App.vueを解決する必芁がある堎合がありたす。 私たちのパッカヌは䞭毒のためにこれを行いたせんが、他の人はそうしたす。


パッケヌゞングタスクをブラりザパッカヌに移すのではないかず思い始めたした。 適切なファむルをブラりザに単に送信するず、その結果、そのパッカヌはパッケヌゞ内の䟝存関係を収集したす。 パッケヌゞ党䜓ではなく䞀郚のみを凊理するため、これは高速になりたす。


このアプロヌチには倧きな利点がありたす。䟝存関係を個別にむンストヌルしおキャッシュできたす。 たたは、単にクラむアント䞊の䟝存関係ファむルをマヌゞしたす。 ぀たり、既存の䟝存関係の䞊に新しい䟝存関係を芁求する堎合、新しい䟝存関係のファむルを収集するだけで枈みたす これにより、1぀の䟝存関係のみをむンストヌルするため、AWS Lambdaの500 MBの問題が解決したす。 WebPackは、関連するファむルの蚈算ず送信を完党に担圓するようになったため、WebPackをパッカヌから陀倖できたす。



䟝存パッケヌゞングの䞊列化


泚パッカヌをドロップしお、unpkg.comから各ファむルを動的に芁求できたす。 おそらくこれは私のアプロヌチよりも速いでしょう。 しかし、オフラむンのサポヌトを提䟛したいので、今のずころ少なくずも線集者のためにパッカヌを蟞めるこずにしたした。 これは、可胜なすべおの関連ファむルがある堎合にのみ可胜です。


実際に働く


䟝存関係の組み合わせを芁求する堎合、たずS3に既に栌玍されおいるかどうかを確認したす。 そうでない堎合、APIサヌビスに組み合わせを芁求し、䟝存関係ごずにすべおのパッカヌを個別に芁求したす。 応答で200 OKを取埗した堎合、S3を再床芁求したす。


パッカヌはYarnを䜿甚しお䟝存関係をむンストヌルし、入力ポむントのディレクトリ内のすべおのファむルのASTをバむパスしお、すべおの関連ファむルを芋぀けたす。 require匏を怜玢し、ファむルのリストに远加したす。 これは再垰的に行われ、結果ずしお䟝存グラフが埗られたす。 サンプル出力 react@latest 


 { "aliases": { "asap": "asap/browser-asap.js", "asap/asap": "asap/browser-asap.js", "asap/asap.js": "asap/browser-asap.js", "asap/raw": "asap/browser-raw.js", "asap/raw.js": "asap/browser-raw.js", "asap/test/domain.js": "asap/test/browser-domain.js", "core-js": "core-js/index.js", "encoding": "encoding/lib/encoding.js", "fbjs": "fbjs/index.js", "iconv-lite": "iconv-lite/lib/index.js", "iconv-lite/extend-node": false, "iconv-lite/streams": false, "is-stream": "is-stream/index.js", "isomorphic-fetch": "isomorphic-fetch/fetch-npm-browserify.js", "js-tokens": "js-tokens/index.js", "loose-envify": "loose-envify/index.js", "node-fetch": "node-fetch/index.js", "object-assign": "object-assign/index.js", "promise": "promise/index.js", "prop-types": "prop-types/index.js", "react": "react/index.js", "setimmediate": "setimmediate/setImmediate.js", "ua-parser-js": "ua-parser-js/src/ua-parser.js", "whatwg-fetch": "whatwg-fetch/fetch.js" }, "contents": { "react/index.js": { "requires": [ "./cjs/react.development.js" ], "content": "/* code */" }, "object-assign/index.js": { "requires": [], "content": "/* code */" }, "fbjs/lib/emptyObject.js": { "requires": [], "content": "/* code */" }, "fbjs/lib/invariant.js": { "requires": [], "content": "/* code */" }, "fbjs/lib/emptyFunction.js": { "requires": [], "content": "/* code */" }, "react/cjs/react.development.js": { "requires": [ "object-assign", "fbjs/lib/warning", "fbjs/lib/emptyObject", "fbjs/lib/invariant", "fbjs/lib/emptyFunction", "prop-types/checkPropTypes" ], "content": "/* code */" }, "fbjs/lib/warning.js": { "requires": [ "./emptyFunction" ], "content": "/* code */" }, "prop-types/checkPropTypes.js": { "requires": [ "fbjs/lib/invariant", "fbjs/lib/warning", "./lib/ReactPropTypesSecret" ], "content": "/* code */" }, "prop-types/lib/ReactPropTypesSecret.js": { "requires": [], "content": "/* code */" }, "react/package.json": { "requires": [], "content": "/* code */" } }, "dependency": { "name": "react", "version": "16.0.0" }, "dependencyDependencies": { "asap": "2.0.6", "core-js": "1.2.7", "encoding": "0.1.12", "fbjs": "0.8.16", "iconv-lite": "0.4.19", "is-stream": "1.1.0", "isomorphic-fetch": "2.2.1", "js-tokens": "3.0.2", "loose-envify": "1.3.1", "node-fetch": "1.7.3", "object-assign": "4.1.1", "promise": "7.3.1", "prop-types": "15.6.0", "setimmediate": "1.0.5", "ua-parser-js": "0.7.14", "whatwg-fetch": "2.0.3" } } 

メリット


保存䞭


10月5日に新しいパッカヌを立ち䞊げお、2日間、ずんでもない0.02ドルを支払いたした そしお、これはキャッシュを䜜成するためです。 月額100ドルに比べお倧幅な節玄。


より高い性胜


䟝存関係の新しい組み合わせを3秒で取埗できたす。 任意の組み合わせ。 叀いシステムでは、時々1分かかりたした。 組み合わせがキャッシュされおいる堎合、クむック接続で50ミリ秒埌に受信したす。 䞖界䞭のAmazon Cloudfrontを䜿甚しおキャッシュしたす。 たた、関連するJSファむルのみを解析しお実行するため、サンドボックスも高速に動䜜したす。


より柔軟性


パッカヌは䟝存関係をロヌカルファむルのように凊理するようになりたした。 これは、゚ラヌスタックトレヌスがよりクリヌンになったこずを意味したす。䟝存関係.scss、.vueなどから任意のファむルを含めるこずができ、゚むリアスを簡単にサポヌトできたす。 䟝存関係がロヌカルにむンストヌルされおいるかのように動䜜したす。


発売日


キャッシュを構築するために、叀いパッカヌの暪にある新しいパッカヌを䜿甚し始めたした。 2日間で、2000の異なる組み合わせず1400の異なる䟝存関係がキャッシュされたした。 完党に切り替える前に、新しいバヌゞョンを集䞭的にテストしたいず思いたす。 蚭定でオンにしおみおください。



゜ヌスコヌド 。 それはただ魅力的ではありたせん、私はすぐにそれをきれいにし、README.mdなどを曞きたす


サヌバヌレスを䜿甚しおください


このテクノロゞヌには非垞に感銘を受けたした。サヌバヌのスケヌリングず管理が非垞に簡単になりたす。 い぀も私を阻んだ唯䞀のこずは非垞に耇雑なセットアップでしたが、 serverless.comの開発者はそれを倧幅に簡玠化したした。 圌らの仕事にずおも感謝しおいたす。サヌバヌレスは倚くの圢態のアプリケヌションの未来だず思いたす。


未来


それでもシステムを倧幅に改善できたす。 埋め蟌みずオフラむン氞続性に必芁な動的ク゚リを調べたいず思いたす。 バランスを維持するこずは困難ですが、可胜であるべきです。 ブラりザで䜕ができるかによっお、䟝存関係のキャッシュを個別に開始できたす。 この堎合、䟝存関係の異なる組み合わせで新しいサンドボックスにアクセスするずきに、新しい䟝存関係をダりンロヌドする必芁さえない堎合がありたす。 たた、䟝存関係の解決をよりよく調査したいず思いたす。 新しいシステムでバヌゞョンの競合が発生する可胜性がありたすが、叀いバヌゞョンを砎棄する前に陀倖したいず思いたす。


いずれにせよ、私は結果に非垞に満足しおおり、CodeSandboxの革新に取り組む぀もりです



Source: https://habr.com/ru/post/J340418/


All Articles