ライブラリのロールアップはありますか?!

前に書く


Rollup was designed with libraries rather than apps in mind, and it is a perfect fit for React’s use case.

これは舞台裏で見ました:リポジトリインフラストラクチャの改善– React Blog。少し驚いたのですが、なぜクラスライブラリだけにこれほど良いことがあるのでしょうか。アプリの作成に適さない理由は何ですか?

零.webpack
ライブラリのロールアップはありますか? !

webpackは、複雑なSPAのモジュール構造に取り組んでいます。非常に魅力的なのは、さまざまなローダーです。


Essentially, webpack loaders transform all types of files into modules that can be included in your application’s dependency graph.

さまざまなリソースの依存関係を一貫した方法で処理し、ローダーを介してリソースタイプの違いをシールドします(jsはモジュール、cssはモジュール、imgもモジュール...)。利点は次のとおりです。


No more carefully placing your files in the right folders and hacked-together scripts for adding hashes to file URLs — webpack can take care of it for you.

その他の非常に強力な機能は次のとおりです。

コード分​​割:実稼働環境でのオンデマンドロード/並列ロード

ツリーシェイク:ビルド時に不要なコードを削除(エクスポート)

HMR:開発中のモジュールのホット交換

Commons Chunk:構築中に共通の依存関係を抽出します

依存関係グラフ:ビルドが完了すると、出力モジュールの依存関係グラフによってバンドルが読み取り可能になります

1.元の意図の
ロールアップは、最初からES6モジュール用です。


Next-generation ES6 module bundler.

当時、AMD、CMD、UMD間のフォーマットの争いは依然として非常に熱く、ES6モジュールはまだブラウザに実装されていませんでした。ロールアップが出たばかり


Rollup was created for a different reason: to build flat distributables of JavaScript libraries as efficiently as possible, taking advantage of the ingenious design of ES2015 modules.

(WebpackとRollupからの引用:同じですが異なる、rollupの作成者によって書かれました)

ES6モジュールメカニズムを駆使して、フラットな構造と優れたパフォーマンスを備えた、ライブラリ用に設計されたクラスライブラリバンドルを構築したいと考えています。

2.主な利点


It solves one problem well: how to combine multiple modules into a flat file with minimal junk code in between.

ロールアップの驚くべき点は、バンドル、特にiife形式のクリーンさです。コンテンツは非常にクリーンで、余分なコードはありません。モジュールが依存関係の順にスプライスされているだけです。

これは、ロールアップのモジュール処理のアイデアに関連しています:


To achieve this, instead of turning modules into functions like many other bundlers, it puts all the code in the same scope, and renames variables so that they don’t conflict. This produces code that is easier for the JavaScript engine to parse, for a human to read, and for a minifier to optimize.

すべてのモジュールは、バンドルファイルの最も外側のスコープにフラットに配置されます。モジュール間にスコープの分離はなく、名前の変更は、同じスコープでの名前の競合の問題を解決するために使用されます。いくつかの明らかな利点:

ランタイムパフォーマンス(分析を容易にするためのフラットなコード構造)

バンドルソースコードの読みやすさ(自然な順序構造、モジュール定義/ジャンプなし)

圧縮を最適化できます(モジュール定義やその他の非圧縮ボイラープレートコードはありません)

これの欠点も明らかです:

モジュールシステムは静的すぎて、HMRなどの機能を実現するのは困難です

ES6モジュールの場合のみ、cjsとumdの依存関係を確実に処理できません(rollup-plugin-commonjsを使用するたびに問題が発生します)

lib専用の場合、最初のポイントがサポートされていなくても問題ありませんが、2番目のポイントは本当に頭痛の種です。2番目の依存関係は制御できません。cjsモジュールをES6モジュールに自動的に変換できないという問題が発生することは常に避けられません。例えば:


‘foo’ is not exported by bar.js (imported by baz.js)

一部のシナリオは、namedExportsを介したトラブルシューティング、または外部またはグローバルを介したトラブルシューティングによって不幸に解決でき、プラグインアプリケーションの順序を調整する必要があるソリューションもあります...しかし、この種の問題を完全に解決する方法はありません。


Webpack gets around the need for namedExports by keeping everything as CommonJS modules and implementing Node’s require system in the browser, which is why the resulting bundles are larger and take longer to start up. Both options are valid, but that’s the tradeoff to be aware of — more config (Rollup, when using modules like React), or larger bundles (webpack).

(引自「名前付きエクスポート」機能またはバグですか?)

cjsはやがて歴史になりますが、現在も現在もnpmにはかなりの数のcjsモジュールがあり、SPAであろうとライブラリであろうと、cjsモジュールの依存関係を処理するという問題に直面しています。

3.選択の原則
アプリにはwebpackを使用し、ライブラリにはRollupを使用します

アプリの構築には、webpackの方が適しています。クラスライブラリの場合は、もちろんロールアップの方が適しています。

アプリを構築するためのwebpackの利点は、次の側面に反映されています。

強力なプラグインエコロジー、主流のフロントエンドフレームワークには対応するローダーがあります

前述のHMR、コード分割、コモンズチャンクなどのアプリ指向の機能サポートはすべて、アプリ開発に必要な機能です。

写真の自動base64、リソースキャッシング(chunkId)、ルートによるコード分割、遅延読み込みなど、Web開発のすべての側面を簡素化します。達成するのは難しくありません。

依存モジュールの信頼性の高い処理は、cjsの問題に直面するロールアップとは異なり、__ webpack_require__にはこれらの問題はありません。

ロールアップにはこれらの利点がなく、コード分割を行うときに解決が容易ではないいくつかの問題が発生します。十分な時間と把握がない場合は、ロールアップをアプリ構築ツールとして簡単に使用しないでください。

ロールアップの利点は、まさにライブラリが追求している高効率バンドルにあります。(React 16のように)少し後退したとしても、パフォーマンスには価値があります。

この原則は、適切なツールを使用して適切なことを行うことのみを示していることに注意してください。これは、ほとんどの一般的なシナリオに適しています。また、ロールアップを使用してAppを構築し、Webpackを使用してクラスライブラリを構築することも非常に一般的です。


That’s not a hard and fast rule — lots of sites and apps are built with Rollup, and lots of libraries are built with webpack. But it’s a good rule of thumb.

通常、ビジネス自体があまり多くのサードパーティモジュールに依存しておらず、スタイル規則がES6モジュールに従っている場合は、ロールアップ(コード分割など)を使用してアプリを構築することも適切です。

PSさらに、ロールアップは、vueファイルから3つの部分を分離し、別々に処理するなど、glupやwebpackなどのストリームベースの拡張機能を実行するのは簡単ではありません(vueプラグインはtsをサポートしていないようです)

4。外部依存関係は

Reactおよびその他のクラス用ですライブラリは、いくつかの理由から、バンドルに組み込まれるのではなく、可能な限りサードパーティの依存関係として分離する必要があります。

パフォーマンスが低下します。たとえば、React16はロールアップ+ GCC(Google Closure Compiler)に切り替えるのに多大な労力を要しました。これは109kbに達しました。一度コンパイルして、解放前に戻しました。

キャッシングには役立ちません。クラスライブラリは頻繁に更新されず、静的リソースとして使用して、キャッシングの利点を十分に活用できます。手動ビルドの内容は、ツールの構成に影響されます。

外部依存関係は、ロールアップの下の外部+グローバル構成を通じてマークできます。


external: ['react', 'react-dom'],
output: {
  globals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  }
}

この方法で生成されたバンドルは次のとおりです。


// iife
(function (React,ReactDOM) {
    //...
}(React,ReactDOM));

// cjs
var React = _interopDefault(require('react'));
var ReactDOM = _interopDefault(require('react-dom'));

したがって、ビジネスコードは通常iifeにパッケージ化され、サードパーティのCDNクラスライブラリがスクリプトを介して参照されます。


<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- 或者聚合的版本 -->
<script crossorigin src="//cdn.jsdelivr.net/combine/npm/[email protected]/umd/react.production.min.js,npm/[email protected]/umd/react-dom.production.min.js"></script>

PSrollupの外部とグローバルは、キーか値か、またはこれら2つを一緒に使用する必要があるかどうかにかかわらず、少し奇妙です。詳細については、[質問]を参照してください。外部とグローバルの違い

リファレンス

WebpackとRollup:同じですが異なる:非常に興味深い見つかりませんでした

ロールアップを使用したサードパーティのJavaScriptの処理

おすすめ

転載: blog.51cto.com/15080030/2592709