一吃引、分離第三方庫(vendor)
把第三方代碼和應(yīng)用本身的代碼一起打包是非常低效的佛析。
因?yàn)闉g覽器會(huì)根據(jù)緩存頭來緩存資源文件栗精,如果文件沒有被改變闯参,文件將會(huì)被緩存從而不用去再次請(qǐng)求 cdn瞻鹏。
為了利用這一特性,我們希望不管應(yīng)用本身的代碼如何改變鹿寨,vendor 文件的 hash 始終恒定不變新博。
用法:
var webpack = require('webpack');
var path = require('path');
module.exports = function(env) {
return {
entry: {
main: './index.js',
vendor: 'moment'
},
output: {
filename: '[chunkhash].[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // 指定公共 bundle 的名字。
})
]
}
}
為第三方庫moment添加一個(gè)單獨(dú)的入口vendor脚草,在不使用CommonsChunkPlugin的情況下赫悄,webpack運(yùn)行后會(huì)生成兩個(gè)bundle,并且兩個(gè)bundle中都會(huì)有moment的代碼馏慨。
CommonsChunkPlugin允許我們從不同的 bundle 中提取所有的公共模塊埂淮,并且將他們加入公共 bundle 中。如果公共 bundle 不存在写隶,那么它將會(huì)創(chuàng)建一個(gè)出來倔撞。
利用這個(gè)特性,我們指定公共bundle的名字與moment的bundle文件一樣慕趴,從而讓CommonsChunkPlugin提取的公共模塊覆蓋moment的bundle文件痪蝇,達(dá)到分離第三方庫的效果。
至此冕房,我們已經(jīng)成功的將第三方代碼提取到了獨(dú)立的bundle躏啰,但上文提到的瀏覽器緩存機(jī)制我們還是無法用上,因?yàn)?vendor 的 hash 在每次構(gòu)建中都會(huì)改變毒费,瀏覽器也必須重新加載文件丙唧。
解決方案:
var webpack = require('webpack');
var path = require('path');
module.exports = function(env) {
return {
entry: {
main: './index.js',
vendor: 'moment'
},
output: {
filename: '[chunkhash].[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'] // 指定公共 bundle 的名字。
})
]
}
};
最終會(huì)生成多一個(gè)mainfest bundle
更多介紹見 webpack優(yōu)化-緩存
二觅玻、分離CSS
1想际、導(dǎo)入 CSS
import 'bootstrap/dist/css/bootstrap.css';
2、使用 css-loader
module.exports = {
module: {
rules: [{
test: /\.css$/,
use: 'css-loader'
}]
}
}
結(jié)果溪厘,CSS和您的JavaScript打包在一起胡本。
這有個(gè)缺點(diǎn),您將無法利用瀏覽器的異步和并行加載CSS的能力畸悬。這樣侧甫,您的網(wǎng)頁必須等待,直到您的整個(gè)JavaScript 包下載完成蹋宦,然后重繪網(wǎng)頁披粟。
3、使用 ExtractTextWebpackPlugin
這個(gè)插件要自己安裝
module.exports = {
module: {
rules: [{
test: /\.css$/,
- use: 'css-loader'
+ use: ExtractTextPlugin.extract({
+ use: 'css-loader'
+ })
}]
},
+ plugins: [
+ new ExtractTextPlugin('styles.css'),
+ ]
}
三冷冗、按需分離
雖然前面幾類資源分離守屉,需要用戶預(yù)先在配置中指定分離模塊,但也可以在應(yīng)用程序代碼中創(chuàng)建動(dòng)態(tài)分離模塊蒿辙。
這可以用于更細(xì)粒度的代碼塊,例如,根據(jù)我們的應(yīng)用程序路由灾常,或根據(jù)用戶行為預(yù)測(cè)。這可以使用戶按照實(shí)際需要加載非必要資源恭取。
四、使用 require.ensure() 分離代碼
require.ensure(dependencies: String[], callback: function(require), chunkName: String)
兩種情況:
// 空數(shù)組作為參數(shù)
require.ensure([], function(require){
require('./a.js');
});
a.js會(huì)被打包到獨(dú)立的bundle熄守,例如entry打包輸出為bundle.js蜈垮,a.js會(huì)被打包為0.bundle.js
//依賴作為參數(shù)
require.ensure(['./a.js'], function(require) {
require('./b.js');
});
上面代碼, a.js 和 b.js 都被打包到一起柠横,而且從主文件束中拆分出來窃款。但只有 b.js 的內(nèi)容被執(zhí)行。a.js 的內(nèi)容僅僅是可被使用牍氛,但并沒有被輸出。
想去執(zhí)行 a.js烟阐,我們需要異步地引用它搬俊,如 require('./a.js'),讓它的 JavaScritp 被執(zhí)行蜒茄。