webpack打包后,浏览器对文件的缓存怎么处理

前端文件在进行版本更迭时,会出现浏览器缓存造成的问题,具体描述为:

以下是我的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内应该是

<body>
    <div id="index"></div>
    <script src="/js/index_v1.js"></script>
</body>

版本2:
版本2内的index页面入口文件为index_v2.js,其中其他文件为[模块名].[hash].js

这时候在index.html中的body内应该是

<body>
    <div id="index"></div>
    <script src="/js/index_v2.js"></script>
</body>

两次打包后的文件名称完全不一样,但是当版本二部署后,浏览器加载index.html页面后,在控制台中显示页面引入的js文件依然是index_v1.js而不会加载index_v2.js。这时候如果刷新浏览器,那么加载的文件又变为index_v2.js。

以上就是当前小小鄙人遇到的问题。


对于浏览器缓存的问题,鄙人有这么点理解,简单的说:

  • 对于nginx中的文件,若文件名称不变,内容发生变化,这时候浏览器会使用缓存的文件,若文件名称发生改变,就是请求的url发生改变,相当于一个新的http请求,就会重新去请求文件。

这样的理解应该是对的,但是对于上述遇到的问题,则让我对这个理解产生怀疑。

另外对于图片缓存

浏览器的缓存可以通过 cache-controlmax-ageexpires。。。,一些参数去设置,网上的一些讲解也非常明白,对于参数的理解也不是很难,但是这些参数在实际应用中确很少谈及,这些参数在那里设置呢,在html文件的 meta 标签中设置,还是在服务器中设置?一直都找不到答案。另外又如何做到对单个图片进行缓存控制呢?


以上实际提出了两个问题:

  1. 浏览器对文件的缓存为何会造成我这样的问题,文件名更改却还会寻找上个版本的文件
  2. 浏览器缓存如何设置,图片缓存能单独设置吗?

望各位大神指点指点,小白前端渴望得到你们答案,谢谢大家!

阅读 7.8k
3 个回答
新手上路,请多包涵

楼主解决了吗,我也遇到同样的问题

  • 问题1. 浏览器对文件的缓存为何会造成我这样的问题,文件名更改却还会寻找上个版本的文件?
    首先你要确定几个情况

    1. 服务端有没有做负载均衡?如果做了负载均衡,发版本又只发了其中几台机器(没有全部机器都发布),那么负载均衡的机制就会导致你这个问题,浏览器访问到不同机器的代码,不同机器上的代码有些机器的是版本1的,有些却是版本2的。
    2. 如果不是负载均衡的问题,那可能是按需加载的hash问题了,确定浏览器已经成功加载404_v2.js了,并且有用到CommonsChunkPlugin么? 如果用了,CommonsChunkPlugin对应的js文件必须要有hash,不然就会导致CommonsChunkPlugin的js文件访问的是缓存的文件,从而去访问老版本文件。
  • 问题2 浏览器缓存如何设置,图片缓存能单独设置吗?
    浏览器缓存要在服务端设置响应头等信息,图片缓存能单独设置,不过一般都是整体设置缓存。

为了更全面认知问题,最好还是把 webpack 配置全放上来

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题