Original translation, please indicate the source when reprinting.
Original address: https://webpack.js.org/guides/production-build/
This page explains how to use webpack for production builds.
automatic mode
Running webpack -p (equivalent to: webpack --optimize-minimize --define process.env.NODE_ENV="'production'" ), it performs the following steps:
- Compression using UglifyJsPlugin
- Run LoaderOptionsPlugin
- Set node environment variables
compression
webpack comes with UglifyJsPlugin which runs UglifyJS to compress output files. This plugin supports all UglifyJS options. Specifying --optimize-minimize on the command line adds the following configuration:
// webpack.config.js const webpack =require('webpack'); module.exports ={ /*...*/ plugins:[ newwebpack.optimize.UglifyJsPlugin({ sourceMap: options.devtool &&(options.devtool.indexOf("sourcemap")>=0|| options.devtool.indexOf("source-map")>=0) }) ] };
So according to the options of devtool , Source Maps will be generated .
Source Maps
We encourage the availability of Source Maps in production . It is very helpful when debugging and benchmarking. webpack can generate inline Source Maps in the bundle file or in a separate file .
In your configuration, use the devtool object to set the type of Source Map . We currently support 7 types of Source Maps . You can find more information about this in the configuration related documentation.
Node environment variables
Running webpack -p (or --define process.env.NODE_ENV="'production'" ) will call DefinePlugin in the following way :
// webpack.config.js const webpack =require('webpack'); module.exports ={ /*...*/ plugins:[ newwebpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }) ] };
DefinePlugin performs a find - replace operation in the source code. Any process.env.NODE_ENV introduced into the code is replaced with " production ". Therefore, checks like if (process.env.NODE_ENV !== 'production') console.log('...') will all be processed as if (false) console.log('...') , and finally use UglifyJS just strips them out.
The manual way: configure multiple environments for webpack
When we need to prepare different configurations for different environments, the easiest way is to write a separate js file for each environment.
dev.js
module.exports =function(env){ return{ devtool:'cheap-module-source-map', output:{ path: path.join(__dirname,'/../dist/assets'), filename:'[name].bundle.js', publicPath: publicPath, sourceMapFilename:'[name].map' }, devServer: port:7777, host:'localhost', historyApiFallback:true, noInfo:false, stats:'minimal', publicPath: publicPath } } }
prod.js
module.exports =function(env){ return{ output:{ path: path.join(__dirname,'/../dist/assets'), filename:'[name].bundle.js', publicPath: publicPath, sourceMapFilename:'[name].map' }, plugins:[ newwebpack.LoaderOptionsPlugin({ minimize:true, debug:false }), newwebpack.optimize.UglifyJsPlugin({ beautify:false, missing: { screw_ie8:true, keep_fnames:true }, compress:{ screw_ie8:true }, comments:false }) ] } }
Add the following code to webpack.config.js :
functionbuildConfig(env){ returnrequire('./config/'+ env +'.js')(env) } module.exports = buildConfig;
And in package.json , when using webpack to compile the application, the code looks like this:
"build:dev":"webpack --env=dev --progress --profile --colors", "build:dist":"webpack --env=prod --progress --profile --colors",
You can see that we passed an environment variable to the webpack.config.js file. In the webpack.config.js file, we use a simple switch to call the correct file for compilation based on the passed environment variables.
A better approach is to have a base config file that puts all the common functionality in, and then configure environment-specific files that can be simply merged using 'webpack-merge' . This avoids code duplication. For example, you can put parsing js , ts , png , jpeg , json , etc. into the following common configuration:
base.js
module.exports =function(){ return{ entry:{ 'polyfills':'./src/polyfills.ts', 'vendor':'./src/vendor.ts', 'main':'./src/main.ts' }, output:{ path: path.join(__dirname,'/../dist/assets'), filename:'[name].bundle.js', publicPath: publicPath, sourceMapFilename:'[name].map' }, resolve:{ extensions:['.ts','.js','.json'], modules:[path.join(__dirname,'src'),'node_modules'] }, module:{ rules:[{ test:/\.ts$/, use:[ 'awesome-typescript-loader', 'angular2-template-loader' ], exclude:[/\.(spec|e2e)\.ts$/] },{ test:/\.css$/, use:['to-string-loader','css-loader'] },{ test:/\.(jpg|png|gif)$/, use:'file-loader' },{ test:/\.(woff|woff2|eot|ttf|svg)$/, use:{ loader:'url-loader', options:{ limit:100000 } } }], }, plugins:[ newForkCheckerPlugin(), newwebpack.optimize.CommonsChunkPlugin({ name:['polyfills','vendor'].reverse() }), newHtmlWebpackPlugin ({ template:'src/index.html', chunksSortMode:'dependency' }) ], }; }
Then use 'webpack-merge' to merge the base configuration with an environment-specific configuration. Let's see an example of merging product files, using 'webpack-merge' to merge the base files together as above:
prod.js (after update)
const webpackMerge =require('webpack-merge'); const commonConfig =require('./base.js'); module.exports =function(env){ returnwebpackMerge(commonConfig(),{ plugins:[ newwebpack.LoaderOptionsPlugin({ minimize:true, debug:false }), newwebpack.DefinePlugin({ 'process.env':{ 'NODE_ENV': JSON.stringify('production') } }), newwebpack.optimize.UglifyJsPlugin({ beautify:false, missing: { screw_ie8:true, keep_fnames:true }, compress:{ screw_ie8:true }, comments:false }) ] }) }
You will find three main update points in our prod.js file.
- Merge ' base.js' with ' webpack-merge '
- We have moved the output into ' base.js' . To emphasize, we refactored ' prod.js' and moved the output property to the common configuration file ' base.js' , which runs through all environments.
- 我们用'DefinePlugin'把'process.env.NODE_ENV'定义为'production'。现在当我们为产品环境编译应用的时候,'process.env.NODE_ENV'的值是'production'将贯穿于整个应用。同样我们可以为每个环境管理各种变量。
你自己决定把那些功能定义为横跨所有环境。我们只是演示了在编译应用时一些典型的可以横跨所有环境的功能。
-- End --