[Translation] webpack official website documentation: Guide -- 6. Code splitting - third-party libraries

Original translation, please indicate the source when reprinting. 

Original address: https://webpack.js.org/guides/code-splitting/

 

A typical application depends on many third-party libraries based on framework or functional requirements. Specific versions of these libraries are used, and the code does not change frequently. In contrast, the code of the application changes frequently.

Packaging application code along with code from third-party libraries can be very inefficient. This is because resource files are cached based on cache header information, and if the content of the cached file has not changed, there is no need to access the cdn . To take advantage of this, we want the hash of the third-party library file to remain the same regardless of changes to the application code.

This can only be achieved if we package the third-party library files and application code separately.

Let's consider a simple application using momentjs , a library commonly used for time formatting.

On your app folder, install moment like below .

npm install --save moment

The index file will import moment as a dependency and output the log of the current time as follows

index.js

var moment =require('moment');
console.log(moment().format());

 

We can use the following configuration to package the application with webpack

Webpack.config.js

var path =require('path');
 
module.exports =function(env){
    return{
        entry:'./index.js',
        output:{
            filename:'[name].[chunkhash].js',
            path: path.resolve(__dirname,'dist')
        }
    }
}

 

Run webpack in your app, and if you check the resulting bundle, you'll see moment and index.js are bundled into bundle.js .

 

multiple entrances

Let's avoid this result by adding a separate entry point for moment , name it vendor

webpack.config.js

var path =require('path');
 
module.exports =function(env){
    return{
        entry:{
            main:'./index.js',
            vendor:'moment'
        },
        output:{
            filename:'[name].[chunkhash].js',
            path: path.resolve(__dirname,'dist')
        }
    }
}

 

Running webpack now , we see that two bundles are generated. If you've checked them, you'll see that moment code is present in both package files! The reason is that moment is a dependency of the main application (eg index.js ) and every entry point will package their dependencies.

It is for this reason that we need to use the CommonsChunkPlugin .

 

CommonsChunkPlugin

This is a fairly complex plugin. It basically allows us to extract common modules from different packages and add them to the common package. If the common package does not exist, make a new one.

We can modify the webpack configuration file like this:

webpack.config.js

var webpack =require('webpack');
var path =require('path');
 
module.exports =function(env){
    return{
        entry:{
            main:'./index.js',
            vendor:'moment'
        },
        output:{
            filename:'[name].[chunkhash].js',
            path: path.resolve(__dirname,'dist')
        },
        plugins:[
            newwebpack.optimize.CommonsChunkPlugin({
                name:'vendor'// Specify the common bundle's name.
            })
        ]
    }
}

 

Now run webpack in your app . Looking at the contents of the package, you will find that the moment code only exists in the vendor package.

 

Default common third-party library code block

You can configure CommonsChunkPlugin instances to only handle third-party libraries.

webpack.config.js

var webpack =require('webpack');
var path =require('path');
 
module.exports =function(){
    return{
        entry:{
            main:'./index.js'
        },
        output:{
            filename:'[name].[chunkhash].js',
            path: path.resolve(__dirname,'dist')
        },
        plugins:[
            newwebpack.optimize.CommonsChunkPlugin({
                name:'vendor',
                minChunks:function(module){
                   // this assumes your vendor imports exist in the node_modules directory
                   return module.context && module.context.indexOf('node_modules')!==-1;
                }
            })
        ]
    };
}

 

manifest file

But if we modify the application code and re-run webpack , we find that the hashes of the third-party library files have changed. Although we have made separate vendor and main packages, we see that when the application code changes, the vendor package also changes. This means that we still can't take advantage of the browser's cache, since the vendor file's hash will change with each compilation, so the browser will have to load the file again.

The problem exists in every compilation, webpack generates some webpack runtime code which helps webpack do its job. When there is only one package, the runtime code lives in that package. When multiple packages are generated, the runtime code is extracted into a common module, the vendor file here.

To prevent this, we need to extract the runtime code into a separate manifest file. Although we generate one more package, this disadvantage will be offset by the long term caching advantage of the vendor file we get.

webpack.config.js

var webpack =require('webpack');
var path =require('path');
 
module.exports =function(env){
    return{
        entry:{
            main:'./index.js',
            vendor:'moment'
        },
        output:{
            filename:'[name].[chunkhash].js',
            path: path.resolve(__dirname,'dist')
        },
        plugins:[
            newwebpack.optimize.CommonsChunkPlugin({
                names:['vendor','manifest']// Specify the common bundle's name.
            })
        ]
    }
};

 

通过上面的webpack配置,我们看到生成了3个包文件。vendor,mainmanifest包。

 

-- End --

Guess you like

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