[译]webpack官网文档 :指南 -- 6.代码分割 - 第三方库

原创翻译,转载请注明出处。 

原文地址:https://webpack.js.org/guides/code-splitting/

 

一个典型的应用基于框架或者功能的需求,会依赖于许多第三方库。会使用这些库的特定版本,代码不会频繁变更。相对比,应用的代码会频繁变更。

连同第三方库的代码一起打包应用代码会非常低效。这是因为会基于缓存头部信息来缓存资源文件,并且缓存的文件如果内容没有变更,就不需要访问cdn。要想利用这个优点,我们希望不管应用代码如何变化,第三方库文件的哈希值保持不变。

只有我们把第三方库文件和应用代码分开打包才能实现。

让我们考虑一个使用momentjs的简单应用,一个通常用于时间格式化的库。

在你的应用文件夹上,像下面这样安装moment

npm install --save moment

index文件将会当作一个依赖来引入moment,并且像下面这样输出当前时间的日志

index.js

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

 

我们可以使用下面的配置,用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')
        }
    }
}

 

在你的应用里运行webpack,如果你检查结果包,你将会看到momentindex.js被打包到bundle.js里。

 

多个入口

让我们为moment增加独立的入口点来避免这个结果,命名它为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')
        }
    }
}

 

现在运行webpack,我们看到生成了两个包。如果你已经检查过它们,你会发现moment代码出现在两个包文件里!原因时moment是主应用(例如:index.js)的依赖,并且每一个入口点都会打包他们的依赖。

正是这个原因,我们需要使用CommonsChunkPlugin

 

CommonsChunkPlugin

这是一个相当复杂的插件。它从根本上允许我们从不同的包里提取出共同模块,把它们加到共通包里。如果共通包不存在就做成一个新的。

我们可以像下面这样修改webpack配置文件:

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.
            })
        ]
    }
}

 

现在在你的应用里运行webpack。查看包的内容会发现moment代码只存在与vendor包里。

 

默认的共通第三方库代码块

你可以配置CommonsChunkPlugin实例让他们只处理第三方库。

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;
                }
            })
        ]
    };
}

 

清单文件

但是如果我们修改应用代码,并重新运行webpack,我们发现三方库文件的哈希值变了。虽然我们做成了分开的vendormain包,我们看到应用代码变化的时候,vendor包也随着变化。这意味着我们仍然不能利用浏览器的缓存这个优点,应为vendor文件的哈希值会随着每次编译而变化,这样的话浏览器将不得不再次加载文件。

这个问题存在于每一次编译里,webpack生成一些webpack运行时代码,它帮助webpack完成它的工作。当只有一个包的时候,运行时代码就会存在于这个包里面。当有多个包生成的时候,运行时代码就会被提取到共通模块里,这里的vendor文件。

为了防止这个,我们需要把运行时代码提取到一个独立的清单文件里。虽然我们多生成了一个包,这个缺点将会被我们得到的vendor文件的长期缓存优点抵消。

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

猜你喜欢

转载自stef.iteye.com/blog/2364786
今日推荐