写在前面
1.浏览器缓存是根据一个appcache文件,当文件中的某些名称发生变化的时候,重新想服务器请求变化了的资源,这就要求:资源文件内部没有变化的文件不能改变名称,资源文件内部变了要能文件名称也变化.
2.要求webpack打包出来的文件名字使用chunkhash,当文件改变,则该文件的名字改变;否则不能变化该文件的名字
一.使用chunkhash命名打包文件
不能使用webpack-dev-server,否则只能使用hash命名
1.webpack.common.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js'
},
plugins: [
new CleanWebpackPlugin(['./dist']),
new HtmlWebpackPlugin({
title: 'cache'
})
],
output: {
// 使用chunkhash为打包文件命名
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
}
}
2.重复运行 npm run build,可能会(也可能不)出现文件名称的hash值改变了,因此需要下面的解决方案
二.提取webpack打包文件中的模板(manifest文件)并打包第三方库
原因如下:
这也是因为 webpack 在入口 chunk 中,包含了某些样板(boilerplate),特别是 runtime 和 manifest。(译注:样板(boilerplate)指 webpack 运行时的引导代码)
1.webpack.common.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
/*entry: {
app: './src/index.js'
},*/
entry:{
app:'./src/index.js',
vendor:[
'lodash'
]
},
plugins: [
new CleanWebpackPlugin(['./dist']),
new HtmlWebpackPlugin({
title: 'cache'
}),
// 将模板文件打包进manifest的文件,保证每次打包都能得到想要的效果
new webpack.optimize.CommonsChunkPlugin({
name:'manifest'
})
],
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
}
}
2.运行npm run build,可以测试
3.打包第三方库
(1)webpack.common.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
/*entry: {
app: './src/index.js'
},*/
entry:{
app:'./src/index.js',
// 第三方库文件为'lodash',...
vendor:[
'lodash'
]
},
plugins: [
new CleanWebpackPlugin(['./dist']),
new HtmlWebpackPlugin({
title: 'cache'
}),
// 此配置必须在前面manifest,lodash文件将被打包成一个独立的vendor.xxxxxx.js文件
new webpack.optimize.CommonsChunkPlugin({
name:'vendor'
}),
new webpack.optimize.CommonsChunkPlugin({
name:'manifest'
})
],
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
}
}
4.向项目中添加print.js,并在src/index.js中引入
print.js
--------
export default function print (text) {
console.log(text);
}
index.js
--------
import _ from 'lodash';
// import Print from './print.js';
import Print from './print.js';
// process.env.NODE_ENV 变量可以被src下的js引用,此处可以做一些开发中才使用的代码,但是需要在webpack.dev.js和webpack.prod.js中定义
if (process.env.NODE_ENV !== 'production') {
console.log('这不是生产环境');
}
if (process.env.NODE_ENV === 'dev') {
console.log('这是开发环境');
}
// 懒加载/按需加载
function component() {
var element = document.createElement('div');
element.innerHTML = _.join(['你好', '申玉超'], '');
// element.onclick = Print.bind(null, 'Hello webpack!');
element.onclick = Print.bind(null, 'Hello webpack!');
return element;
}
document.body.appendChild(component());
5.运行npm run build,按照常理,vendor并未改变,名字也是不应该改变的,但是事实是改变了,此处需要修改webpack.common.js
原因如下:
这是因为每个 module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变—官网所述
解决:
HashedModuleIdsPlugin(webpack自带插件)
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
/*entry: {
app: './src/index.js'
},*/
entry:{
app:'./src/index.js',
vendor:[
'lodash'
]
},
plugins: [
new CleanWebpackPlugin(['./dist']),
new HtmlWebpackPlugin({
title: 'cache'
}),
// 使用HashedModuleIdsPlugin会保持vendor文件名不变
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name:'vendor'
}),
new webpack.optimize.CommonsChunkPlugin({
name:'manifest'
})
],
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, './dist')
}
}