この記事では、React + Webpack の構築とパッケージ化の最適化について紹介し、参考にしていきます。
babel -react-optimize を使用して React コードを最適化します
未使用のライブラリをチェックし、インポート参照を削除します
lodash、echart などの使用ライブラリをオンデマンドでパッケージ化します
lodash は babel-plugin を使用して最適化できます-ロダッシュ。
は、babel-react-optimizeのbabel-plugin-transform-react-remove-prop-typesプラグインを使用することに注意してください。通常、コード内でコンポーネントの PropType を参照しなくても、まったく問題ありません。このプラグインをコンポーネントで使用すると、問題が発生する可能性があります。
詳細については、次を参照してください:
https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types#is-it-safe
Webpack のビルドとパッケージの最適化Webpackビルドとパッケージの存在 問題は主に次の 2 つの側面に焦点を当てています:
Webpack.DDLPlugin および HappyPack ビルド速度を向上させます。詳細については、DMP DDLPlugin に関する Xiaoming のドキュメントを参照してください。元のテキストは次のとおりです:
Webpack.DLLPlugin
webpack.dll.config.js の追加
は主に DllPlugin プラグインを使用して、いくつかのサードパーティ リソースを個別にパッケージ化し、それらを manages.json 構成ファイルに配置します。
このように、コンポーネントでの更新後、これらのサードパーティ リソースは再構築されません
npm run dllを実行すると、dllディレクトリにvendor-manifest.jsonとvendor.dll.jsの2つのファイルが生成されます
webpack.dev.config.jsファイルを設定し、DllReferencePluginプラグインを追加して指定しますベンダーマニフェスト .json ファイル
new webpack.DllReferencePlugin({ context: join(__dirname, 'src'), manifest: require('./dll/vendor-manifest.json') })
html を変更します
<% if(htmlWebpackPlugin.options.NODE_ENV ==='development'){ %> <script src="dll/vendor.dll.js"></script> <% } %>
htmlWebpackPlugin プラグインの NODE_ENV パラメータを設定する必要があることに注意してください
Happypackマルチスレッド、キャッシュなどを通じてリビルド効率を向上させます。 https:// github.com/amireh/happypack
webpack.dev.config.js でさまざまなリソースに対して複数の HappyPack (1 js、1 less など) を作成し、id を設定します
new HappyPack({ id: 'js', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['babel-loader?babelrc&cacheDirectory=true'], }), new HappyPack({ id: 'less', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['css-loader', 'less-loader'], })
module.rules で happypack/loader として使用するように設定します。 ID を設定します
{ test: /\.js$/, use: [ 'happypack/loader?id=js' ], exclude: /node_modules/ }, { test: /\.less$/, loader: extractLess.extract({ use: ['happypack/loader?id=less'], fallback: 'style-loader' }) }
まず、バンドル全体、バンドルの構成要素、および各コンポーネントのサイズを分析する必要があります。
ここでは Webpack-bundle-analyzer をお勧めします。インストール後、プラグインを webpack.dev.config.js に追加するだけで、以下に示すように、各起動後に分析結果が Web サイト上で自動的に開かれます
plugins.push( new BundleAnalyzerPlugin());
さらに、パッケージ化プロセスはjson ファイルとして出力されます
webpack --profile --json -> stats.json
次に、分析のために次の 2 つの Web サイトに移動します
bundle.js サイズが過剰になる問題の解決策は次のとおりです:
必ず webpack.DefinePlugin を起動し、運用環境の webpack.optimize.UglifyJsPlugin。
const plugins = [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: false //eslint-disable-line } }) ]
プロジェクトのビジネス コードは非常に頻繁に変更されるため、サードパーティ ライブラリのコードの変更頻度は比較的低くなります。ビジネス コードと 3 番目のライブラリが同じチャンクにパッケージ化されている場合、ビルドごとに、ビジネス コードが 1 行だけ変更された場合でも、サードパーティ ライブラリのコードが変更されなかった場合でも、チャンク全体のハッシュは前回とは異なります。これは私たちが望む結果ではありません。私たちが望んでいるのは、サードパーティ ライブラリのコードが変更されない場合、構築時に対応するハッシュが変更されないことを確認し、ブラウザ キャッシュを使用してページ読み込みのパフォーマンスを向上させ、ページ読み込みを短縮できるようにすることです。時間。
そのため、3 番目のライブラリのコードをベンダー チャンクに個別に分割し、ビジネス コードから分離することができます。このように、ビジネス コードがどのように変更されても、サードパーティのライブラリ コードが変更されない限り、対応するハッシュは変更されません。
まず、エントリは 2 つのアプリとベンダーの 2 つのチャンクを構成します
entry: { vendor: [path.join(__dirname, 'dll', 'vendors.js')], app: [path.join(__dirname, 'src/index')] }, output: { path: path.resolve(__dirname, 'build'), filename: '[name].[chunkhash:8].js' },
ここで、vendros.js は、ベンダーにどのサードパーティ ライブラリを含める必要があるかを独自に定義したものです。次のとおりです。
require('babel-polyfill'); require('classnames'); require('intl'); require('isomorphic-fetch'); require('react'); require('react-dom'); require('immutable'); require('redux');
次に、CommonsChunkPlugin を通じて 3 番目のライブラリを分割します
plugins.push( // 拆分第三方库 new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' }), // 拆分 webpack 自身代码 new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', minChunks: Infinity }) );
上面的配置有两个细节需要注意
使用 chunkhash 而不用 hash
单独拆分 webpack 自身代码
使用 chunkhash 而不用 hash
先来看看这二者有何区别:
hash 是 build-specific ,任何一个文件的改动都会导致编译的结果不同,适用于开发阶段
chunkhash 是 chunk-specific ,是根据每个 chunk 的内容计算出的 hash,适用于生产
因此为了保证第三方库不变的情况下,对应的 vendor.js 的 hash 也要保持不变,我们再 output.filename 中采用了 chunkhash
单独拆分 webpack 自身代码
Webpack 有个已知问题:
webpack 自身的 boilerplate 和 manifest 代码可能在每次编译时都会变化。
这导致我们只是在 入口文件 改了一行代码,但编译出的 vendor 和 entry chunk 都变了,因为它们自身都包含这部分代码。
这是不合理的,因为实际上我们的第三方库的代码没变,vendor 不应该在我们业务代码变化时发生变化。
因此我们需要将 webpack 这部分代码分离抽离
new webpack.optimize.CommonsChunkPlugin({ name: "runtime", minChunks: Infinity }),
其中的 name 只要不在 entry 即可,通常使用 "runtime" 或 "manifest" 。
另外一个参数 minChunks 表示:在传入公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks。数量必须大于等于2,或者少于等于 chunks的数量,传入 Infinity 会马上生成 公共chunk,但里面没有模块。
拆分公共资源
同 上面的拆分第三方库一样,拆分公共资源可以将公用的模块单独打出一个 chunk,你可以设置 minChunk 来选择是共用多少次模块才将它们抽离。配置如下:
new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2, }),
是否需要进行这一步优化可以自行根据项目的业务复用度来判断。
开启 gzip
使用 CompressionPlugin 插件开启 gzip 即可:
// 添加 gzip new CompressionPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: /\.(js|html)$/, threshold: 10240, minRatio: 0.8 })
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上がReact と Webpack を使用してパッケージングを最適化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。