[译]webpack官网文档 :指南 -- 9.正式产品的编译
原创翻译,转载请注明出处。
原文地址:https://webpack.js.org/guides/production-build/
这一页解释了怎样使用webpack来做正式产品编译。
自动方式
运行webpack –p(等同于:webpack --optimize-minimize --define process.env.NODE_ENV="'production'"),它会执行以下的步骤:
- 使用UglifyJsPlugin压缩
- 运行LoaderOptionsPlugin
- 设定节点环境变量
压缩
webpack自带UglifyJsPlugin,它运行UglifyJS来压缩输出文件。这个插件支持所有的UglifyJS选项。在命令行指定--optimize-minimize,就会添加下面的配置:
// 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) }) ] };
因此依据devtool的选项,会生成Source Maps。
Source Maps
我们鼓励在产品里可用Source Maps。它在调试和基准测试的时候非常有帮助。webpack可以在包文件里或者在单独的文件里生成行内Source Maps。
在你的配置里,使用devtool对象来设定Source Map的类型。我们目前支持7种Source Maps类型。你可以在配置相关的文档里找到找到更多的相关信息。
节点环境变量
运行 webpack –p (或者--define process.env.NODE_ENV="'production'"),就会以下面的方式调用DefinePlugin:
// webpack.config.js const webpack =require('webpack'); module.exports ={ /*...*/ plugins:[ newwebpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }) ] };
DefinePlugin在原代码里执行查找-替换操作。任何被引入代码里的process.env.NODE_ENV都被替换成“production”。因此,像if (process.env.NODE_ENV !== 'production') console.log('...')的检查都会被处理为if (false) console.log('...'),最后使用UglifyJS就把它们剔除掉了。
手动方式:为webpack配置多个环境
当我们需要为不同的环境准备不同配置的话,最简单的方式就是为每一个环境写一个独立的js文件。
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, mangle:{ screw_ie8:true, keep_fnames:true }, compress:{ screw_ie8:true }, comments:false }) ] } }
在webpack.config.js里添加下面的代码:
functionbuildConfig(env){ returnrequire('./config/'+ env +'.js')(env) } module.exports = buildConfig;
并且在package.json里,使用webpack来编译应用的时候,代码像这样:
"build:dev":"webpack --env=dev --progress --profile --colors", "build:dist":"webpack --env=prod --progress --profile --colors",
你可以看到我们给webpack.config.js文件传递了一个环境变量。在webpack.config.js文件里我们使用了一个简单的开关,根据传递过来的环境变量调用正确的文件,来进行编译。
一个更好的方法是有一个基础的配置文件,把所有的共同功能都放进去,然后再配置环境特定的文件,使用’webpack-merge’就可以简单的合并它们。这样可以避免代码重复。例如,你可以把解析js,ts,png,jpeg,json等等放到下面这样的共通配置里:
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' }) ], }; }
然后用’webpack-merge’把基础配置和一个环境特定配置合并到一起。让我们看看一个合并产品文件的例子,像上面说的,用’webpack-merge’把基础文件合并到一起:
prod.js(更新后)
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, mangle:{ screw_ie8:true, keep_fnames:true }, compress:{ screw_ie8:true }, comments:false }) ] }) }
你会发现在我们的prod.js文件里有三个主要更新点。
- 用‘webpack-merge'合并'base.js'
- 我们已经把output移到'base.js'里。强调一点,我们重构'prod.js',把output属性移到共通配置文件'base.js'里,它贯穿于所有的环境。
- 我们用'DefinePlugin'把'process.env.NODE_ENV'定义为'production'。现在当我们为产品环境编译应用的时候,'process.env.NODE_ENV'的值是'production'将贯穿于整个应用。同样我们可以为每个环境管理各种变量。
你自己决定把那些功能定义为横跨所有环境。我们只是演示了在编译应用时一些典型的可以横跨所有环境的功能。
-- End --