主要是介绍之前在webpack1中忽略的以及v2版本中新加的一些东西。
1. caching(缓存)
浏览器为了不重复加载相同的资源,因此加入了缓存功能。通常如果请求的文件名没有变的话,浏览器就认为你请求了相同的资源,因此加载的文件就是从缓存里面拿取的,这样就会造成一个问题,实际上确实你的文件内容变了,但是文件名没有变化,这样还是从缓存中加载文件的话,就出事了。
那么,之前传统的做法就是给每个文件打上加上版本号,例如这样:
app.js?version=1
app.css?version=1
每次变动的时候就给当前的版本号加1,但是如果每次只有一个文件内容变化就要更新所有的版本号,那么没有改变的文件对于浏览器来说,缓存就失效了,需要重新加载,这样就很浪费了。那么,结合数据摘要算法,版本号根据文件内容生成,那么现在的版本可能是这样的。
// before
app.js?version=0add34
app.css?version=1ef4a2
// after
// change app.js content
app.js?versoin=2eda1c
app.css?version=1ef4a2
关于怎么部署前端代码,可以查看大公司怎样开发和部署前端代码
webpack为我们提供了更简单的方式,为每个文件生成唯一的哈希值。为了找到对应的入口文件对应的版本号,我们需要获取统计信息,例如这样的:
{
"main.js": "main.facdf96690cca2fec8d1.js",
"vendor.js": "vendor.f4ba2179a28531d3cec5.js"
}
同时,我们结合html-webpack-plugin
使用的话,就不需要这么麻烦,他会自动给文件带上对应的版本。具体看法参看之前写的webpack1知识梳理,那么我们现在的配置变成了这个样子:
npm install webpack-manifest-plugin --save-dev
// webpack.config.js
module.exports = {
entry : { /* ... */ },
output : {
path : path.resolve(__dirname, 'build-init'),
filename : '[name].[chunkhash].js',
chunkFilename : '[name].[chunkhash].js'
},
module : {
// ...
},
plugins : [
new htmlWebpackPlugin({
title : 'webpack caching'
}),
new WebpackManifestPlugin()
]
}
html引入情况
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack caching</title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="main.facdf96690cca2fec8d1.js"></script><script type="text/javascript" src="vendor.f4ba2179a28531d3cec5.js"></script></body>
</html>
WARNNING:
不要在开发环境下使用[chunkhash],因为这会增加编译时间。将开发和生产模式的配置分开,并在开发模式中使用[name].js的文件名,在生产模式中使用[name].[chunkhash].js文件名。
为了使文件更小化,webpack使用标识符而不是模块名称,在编译的时候会生成一个名字为manifest的chunk块,并且会被放入到entry中。那么当我们更新了部分内容的时候,由于hash值得变化,会引起manifest块文件重新生成,这样就达不到长期缓存的目的了。webpack提供了一个插件ChunkManifestWebpackPlugin
,它会将manifest映射提取到一个单独的json文件中,这样在manifest块中只需要引用而不需要重新生成,所以最终的配置是这样的:
var path = require('path'),
webpack = require('webpack'),
htmlWebpackPlugin = require('html-webpack-plugin'),
ChunkManifestWebpackPlugin = require('chunk-manifest-webpack-plugin'),
WebpackChunkHash = require('webpack-chunk-hash');
module.exports = {
entry : {
main : path.resolve(__dirname, 'js/app.js'),
vendor : path.resolve(__dirname, 'js/vendor.js')
},
output : {
path : path.resolve(__dirname, 'build'),
filename : '[name].[chunkhash].js',
chunkFilename : '[name].[chunkhash].js'
},
module : {
// ...
},
plugins : [
new webpack.optimize.CommonsChunkPlugin({
name : ['vendor', 'manifest'],
minChunks : Infinity
}),
new webpack.HashedModuleIdsPlugin(),
new WebpackChunkHash(),
new htmlWebpackPlugin({
title : 'webpack caching'
}),
new ChunkManifestWebpackPlugin({
filename : 'chunk-mainfest.json',
manifestVariable : 'webpackManifest',
inlineManifest : true
})
]
}
tips:如果还不是很明白,去对比一下加了ChunkManifestWebpackPlugin
和没加的区别就可以清楚的感受到了。在本文的代码文件夹caching
中可以看到这一差别