[译]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 --

 

相关推荐