前端文件在进行版本更迭时,会出现浏览器缓存造成的问题,具体描述为:
以下是我的webpack配置
module.exports = {
entry: {
dashboard: "./dev/CloudPlatform/index.js",
logIn: "./dev/CloudPlatform/login.js",
archives: "./dev/Archives/archives.js",
"404": "./dev/ERROR/404.js",
activateRP: "./dev/CloudPlatform/activateRP.js"
},
output: {
path: path.resolve(__dirname, "build/js"),
publicPath: "/js/",
chunkFilename: "[name].[hash].js",
filename: "[name]_v5.js"
},
externals: {
jquery: "$",
react: "React",
"react-dom": "ReactDOM",
"react-router": "ReactRouter"
},
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("production")
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
},
comments: false
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["es2015", "react"],
plugins: [
"transform-object-rest-spread",
"transform-class-properties"
]
}
}
},
{
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoader: 1
}
},
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("autoprefixer")({
browsers: [
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 9" // React doesn't support IE8 anyway
],
flexbox: "no-2009"
})
]
}
}
]
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: loader => [
require("autoprefixer")({
browsers: [
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 9" // React doesn't support IE8 anyway
],
flexbox: "no-2009"
})
]
}
},
"less-loader"
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192,
name: "../images/[name].[ext]"
}
},
{
loader: "image-webpack-loader",
options: {
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: "65-90",
speed: 4
}
}
}
]
},
{
test: /\.(woff|woff2|svg|eot|ttf)\??.*$/,
use: [
{
loader: "file-loader",
options: {
name: "../font/[name].[ext]"
}
}
]
}
]
}
};
以index.html页面为例,生成两个版本的前端文件:
版本1:
filename可规定index.html页面需要引入的入口js文件名称,第一个版本可为index.html页面生成index_v1.js入口文件,index页面内其他的按需加载的文件可生成名称为[模块名].[hash].js。(hash在每次打包后会改变)。
这时候在index.html中的body内应该是
版本2:
版本2内的index页面入口文件为index_v2.js,其中其他文件为[模块名].[hash].js
这时候在index.html中的body内应该是
两次打包后的文件名称完全不一样,但是当版本二部署后,浏览器加载index.html页面后,在控制台中显示页面引入的js文件依然是index_v1.js而不会加载index_v2.js。这时候如果刷新浏览器,那么加载的文件又变为index_v2.js。
以上就是当前小小鄙人遇到的问题。
对于浏览器缓存的问题,鄙人有这么点理解,简单的说:
对于nginx中的文件,若文件名称不变,内容发生变化,这时候浏览器会使用缓存的文件,若文件名称发生改变,就是请求的url发生改变,相当于一个新的http请求,就会重新去请求文件。
这样的理解应该是对的,但是对于上述遇到的问题,则让我对这个理解产生怀疑。
另外对于图片缓存
浏览器的缓存可以通过 cache-control,max-age,expires。。。,一些参数去设置,网上的一些讲解也非常明白,对于参数的理解也不是很难,但是这些参数在实际应用中确很少谈及,这些参数在那里设置呢,在html文件的 meta 标签中设置,还是在服务器中设置?一直都找不到答案。另外又如何做到对单个图片进行缓存控制呢?
以上实际提出了两个问题:
浏览器对文件的缓存为何会造成我这样的问题,文件名更改却还会寻找上个版本的文件
浏览器缓存如何设置,图片缓存能单独设置吗?
望各位大神指点指点,小白前端渴望得到你们答案,谢谢大家!
回答
楼主解决了吗,我也遇到同样的问题
问题1. 浏览器对文件的缓存为何会造成我这样的问题,文件名更改却还会寻找上个版本的文件?
首先你要确定几个情况
服务端有没有做负载均衡?如果做了负载均衡,发版本又只发了其中几台机器(没有全部机器都发布),那么负载均衡的机制就会导致你这个问题,浏览器访问到不同机器的代码,不同机器上的代码有些机器的是版本1的,有些却是版本2的。
如果不是负载均衡的问题,那可能是按需加载的hash问题了,确定浏览器已经成功加载404_v2.js了,并且有用到CommonsChunkPlugin么? 如果用了,CommonsChunkPlugin对应的js文件必须要有hash,不然就会导致CommonsChunkPlugin的js文件访问的是缓存的文件,从而去访问老版本文件。
问题2 浏览器缓存如何设置,图片缓存能单独设置吗?
浏览器缓存要在服务端设置响应头等信息,图片缓存能单独设置,不过一般都是整体设置缓存。
为了更全面认知问题,最好还是把 webpack 配置全放上来
楼主解决了吗,我也遇到同样的问题