[Translation] webpack official website documentation: Guide -- 9. Compilation of the official product

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 --

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326801312&siteId=291194637