React + Webpack construction and packaging optimization, reactwebpack

Source: Internet
Author: User

React + Webpack construction and packaging optimization, reactwebpack

This article describes how to optimize React + Webpack construction and packaging. The details are as follows:

Use babel-react-optimize to optimize the React code

Check unused libraries and remove import references

Package the class libraries as needed, such as lodash and echart.

Lodash can be optimized using babel-plugin-lodash.

Note that

Babel-plugin-transform-react-remove-prop-types is used in babel-react-optimize. Under normal circumstances, if you do not reference the PropTypes of the component in the code, it is completely OK. If your component is used, using this plug-in may cause problems.

For details, see:

Https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types#is-it-safe

Webpack build packaging Optimization

Webpack build and package mainly involves the following two problems:

  1. Slow Webpack Construction
  2. The size of the Webpack package is too large.

Slow Webpack Construction

You can use Webpack. DDLPlugin and HappyPack to increase the building speed. For more information, see the document of James in DMP DDLPlugin. The original article is as follows:

Webpack. DLLPlugin

Add a webpack. dll. config. js
A DllPlugin plug-in is used to independently package some third-party resources and put them in a manifest. json configuration file,

In this way, after the component is updated, the third-party resources will not be re-built,

  1. Independently configure the dll/vendors. js file and provide it to webpack. dll. config. js.
  2. Modify package. json

Add "dll": "webpack -- config webpack. dll. config. js -- progress -- colors" to scripts ",.

After the npm run dll is executed, two file vendor-manifest.json files will be produced under the dll Directory, vendor. dll. js

Configure the webpack. dev. config. js file, add a DllReferencePlugin plug-in, and specify the vendor-manifest.json File

new webpack.DllReferencePlugin({ context: join(__dirname, 'src'), manifest: require('./dll/vendor-manifest.json')})

Modify html

<% if(htmlWebpackPlugin.options.NODE_ENV ==='development'){ %> <script src="dll/vendor.dll.js"></script><% } %>

Note: You must configure the NODE_ENV parameter in the htmlWebpackPlugin plug-in.

Happypack

Improve rebuild efficiency https://github.com/amireh/happypack by multithreading, caching, and other methods

Create multiple happypacks for different resources in webpack. dev. config. js, such as one in js and one in less, and set the 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'],})

In module. rules, configure use as happypack/loader and Set id

{ test: /\.js$/, use: [ 'happypack/loader?id=js' ], exclude: /node_modules/}, { test: /\.less$/, loader: extractLess.extract({ use: ['happypack/loader?id=less'], fallback: 'style-loader' })}

Reduce the size of the Webpack package file

First, we need to analyze the entire bundle, which is composed of and the size of each component.

Webpack-bundle-analyzer is recommended here. After the installation, add the plug-in webpack. dev. config. js to automatically open the analysis results on the website after each start, as shown in figure

plugins.push( new BundleAnalyzerPlugin());

In addition, the packaging process can be output as a json file.

webpack --profile --json -> stats.json

Then go to the following two websites for analysis

  1. Webpack/analyze
  2. Webpack Chart

The preceding graph analysis shows the composition and size of bundle. js.

The solution to bundle. js's bulky size is as follows:

  1. Enable compression and Other plug-ins in the production environment to remove unnecessary plug-ins
  2. Split Business Code with third-party libraries and public modules
  3. Enable gzip compression for webpack
  4. Load as needed

Enable compression and Other plug-ins in the production environment to remove unnecessary plug-ins

Make sure to start webpack. DefinePlugin and webpack. optimize. UglifyJsPlugin in the production environment.

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  }  })   ]

Split Business Code with third-party libraries and public modules

Because the Business Code of the Project changes frequently, the code changes of third-party libraries are less frequently. If you package the Business Code and the third database to the same chunk, even if the Business Code is changed to only one line during each build, even if the code of the third-party database is not changed, the hash of the entire chunk is different from the previous one. This is not the expected result. What we want is that if the code of the third-party library does not change, we should also ensure that the corresponding hash does not change during the construction so that the browser cache can be used, it can improve page loading performance and shorten page loading time.

Therefore, the code of the third database can be separately split into the vendor chunk, which is separated from the Business Code. In this way, even if the Business Code changes, as long as the third-party library code does not change, the corresponding hash will not change.

First, configure two chunks for the entry app and for the vendor app.

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'},

Among them, vendros. js is a custom third-party library that needs to be included in the vendor, as follows:

require('babel-polyfill');require('classnames');require('intl');require('isomorphic-fetch');require('react');require('react-dom');require('immutable');require('redux');

Then split the third library through CommonsChunkPlugin

Plugins. push (// split the third-party library new webpack. optimize. commonsChunkPlugin ({name: 'vendor'}), // split the webpack code into new webpack. optimize. commonsChunkPlugin ({name: 'runtime', minChunks: Infinity }));

The configuration above has two details to note:

  1. Use chunkhash instead of hash
  2. Separate split webpack code

Use chunkhash instead of hash

Let's take a look at the differences between the two:

  1. Hash is build-specific. Any changes to a file may lead to different compilation results. It is applicable to the development stage.
  2. Chunkhash is a chunk-specific hash calculated based on the content of each chunk and is suitable for production.

Therefore, in order to ensure that the hash of the corresponding vendor. js Library remains unchanged, chunkhash is used in output. filename.

Separate split webpack code

Webpack has a known problem:

The boilerplate and manifest codes of webpack may change at each compilation.

As a result, we only changed a line of code in the entry file, but both the compiled vendor and entry chunk have changed because they all contain this part of code.

This is unreasonable, because in fact the code of our third-party library has not changed, and vendor should not change when our business code changes.

Therefore, we need to separate the webpack code.

new webpack.optimize.CommonsChunkPlugin({   name: "runtime",   minChunks: Infinity}),

If the name is not an entry, "runtime" or "manifest" is usually used ".

The minChunks parameter indicates the minimum number of chunks that need to be included before the public chunk (commons chunk) is passed in. If the number must be greater than or equal to 2 or less than the number of chunks, the public chunk will be generated immediately after Infinity is passed in, but there is no module in it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.