Webpackのdll機能

4146 ワード

最近Webpackを使って穴に遭遇しました.
フロントエンドプロジェクトを構築する際、サードパーティライブラリ(vendors)と自分で書いたコードを別々にパッケージ化することを望んでいます.サードパーティライブラリは常にパッケージ更新を必要としないためです.このWebpackのドキュメントは、CommonsChunkPluginでサードパーティ製ライブラリを個別にパッケージ化することをお勧めします.
entry: {
  vendor: ["jquery", "other-lib"],
  app: "./entry"
}
new CommonsChunkPlugin({
  name: "vendor",

  // filename: "vendor.js"
  // (Give the chunk a different name)

  minChunks: Infinity,
  // (with more entries, this ensures that no other module
  //  goes into the vendor chunk)
})

通常、キャッシュに対抗するために、販売ファイルのファイル名にhashの接尾辞を追加します.しかし、app部分のコードを編集した後、再パッケージしてみると、vendorのhashも変化しています.
これは、リリースされるたびにvendorコードが更新されることを意味します.コードを変更していなくても.これは私たちが別々に梱包する初心に合わない.
問題を持ってGithubの議論を見て、神器を見つけました:dll.
DllはWebpackが最近新しく追加した機能で、私はネット上で中国語の紹介を見つけていないので、ここで簡単に紹介します.
Dllという概念はWindowsシステムのdllを参考にしているはずです.dllパッケージは、純粋な依存ライブラリであり、それ自体は実行できません.appへの参照に使用されます.
dllをパッケージングするとき、Webpackはすべての含まれているライブラリをインデックスにしてmanifestファイルに書きますが、dllを参照するコード(dll user)はパッケージングするときに、このmanifestファイルを読み込むだけでいいです.
これにはいくつかのメリットがあります.
  • Dllパッケージ以降は独立して存在し、含まれるライブラリが増減、アップグレードされていない限りhashも変化しないため、ライン上のdllコードはバージョンのリリースに伴って頻繁に更新する必要はありません.
  • App部分コード修正後、app部分のコードをコンパイルするだけで、dll部分は、含まれるライブラリが増減、アップグレードされていない限り、再パッケージする必要はありません.これにより、コンパイルのたびに速度が大幅に向上します.
  • は、複数のプロジェクトがあり、同じ依存ライブラリを使用していると仮定し、1つのdllを共有することができます.

  • どのように使いますか?
    まず、dllのプロファイルを作成します.entryはサードパーティ製ライブラリのみを含みます.
    const webpack = require('webpack');
    
    const vendors = [
      'antd',
      'isomorphic-fetch',
      'react',
      'react-dom',
      'react-redux',
      'react-router',
      'redux',
      'redux-promise-middleware',
      'redux-thunk',
      'superagent',
    ];
    
    module.exports = {
      output: {
        path: 'build',
        filename: '[name].[chunkhash].js',
        library: '[name]_[chunkhash]',
      },
      entry: {
        vendor: vendors,
      },
      plugins: [
        new webpack.DllPlugin({
          path: 'manifest.json',
          name: '[name]_[chunkhash]',
          context: __dirname,
        }),
      ],
    };
    
    webpack.DllPluginのオプションのうち、pathはmanifestファイルの出力パスである.nameはdll暴露の対象名であり、output.libraryと一致しなければならない.contextは、次に構成されるdll userと一致するパケットパスを解析するコンテキストである.
    Webpackを実行すると、2つのファイルが出力されます.1つはパッケージされたvendorです.js、一つはmanifestです.json、こんな顔をしています.
    {
      "name": "vendor_ac51ba426d4f259b8b18",
      "content": {
        "./node_modules/antd/dist/antd.js": 1,
        "./node_modules/react/react.js": 2,
        "./node_modules/react/lib/React.js": 3,
        "./node_modules/react/node_modules/object-assign/index.js": 4,
        "./node_modules/react/lib/ReactChildren.js": 5,
        "./node_modules/react/lib/PooledClass.js": 6,
        "./node_modules/react/lib/reactProdInvariant.js": 7,
        "./node_modules/fbjs/lib/invariant.js": 8,
        "./node_modules/react/lib/ReactElement.js": 9,
        
        ............

    Webpackは各ライブラリに番号付けインデックスを行い、その後のdll userはこのファイルを読み取り、idで直接参照することができます.
    Dll userの構成:
    const webpack = require('webpack');
    
    module.exports = {
      output: {
        path: 'build',
        filename: '[name].[chunkhash].js',
      },
      entry: {
        app: './src/index.js',
      },
      plugins: [
        new webpack.DllReferencePlugin({
          context: __dirname,
          manifest: require('./manifest.json'),
        }),
      ],
    };
    DllReferencePluginのオプションのうち、contextは、Webpackがmanifestのライブラリに一致するパスを導くために、以前と一致する必要がある.manifestは、さっき出力したmanifestファイルを導入するために使用されます.
    Webpackを実行すると、次の結果が得られます.
    分離しないで梱包した結果を比較します.
    スピードが速くなり、ファイルも小さくなりました.
    普段開発する時、コードを修正して再コンパイルする速度が大幅に減少し、時間を節約します.
    複数のプロジェクトがある場合は、同じライブラリを使用して、パッケージ化時に同じmanifestファイルを参照することで、プロジェクト間で共有できます.
    参照先:
  • https://webpack.github.io/docs/list-of-plugins.html#dllplugin
  • https://github.com/webpack/webpack/tree/master/examples/dll