How Can I Make Webpack Use a Cache-Busting Suffix?

六月ゝ 毕业季﹏ 提交于 2020-01-09 09:01:24

问题


Before Webpack I would always rely on the following pattern for "cache-busting":

<script src="foo.js?cacheBust=12345" />

where 12345 was a token the sever generated for me on every build (it could be a Git hash, although in my case it isn't).

With Webpack I now have two files: build.js and chunk.1.js. Since I bring the first one in with a normal script tag I can use the above pattern:

<script src="build.js?cacheBust=12345" />

However, at that point build.js goes and fetches chunk.1.js, and when it does it doesn't include the cache-busting suffix.

I would like for Webpack to automatically append the ?cacheBust=12345, but I don't know the 12345 part at build time, so I can't include it in my webpack.config. Instead, I have to wait until the HTML page is evaluated, at which point I get the token from the server.

So, my question is, is there any way to have Webpack look at the parameter used to fetch the initial file (eg. ?cacheBust=12345) and append that same parameter when fetching other files?


回答1:


You can simply do this

output: {
    filename: '[name].js?t=' + new Date().getTime(),
    chunkFilename: '[name]-chunk.js?t=' + new Date().getTime(),
    publicPath: './',
    path: path.resolve(__dirname, 'deploymentPackage')
}



回答2:


If you would like to achieve cache busting in "webpack way":

1. Hash name of output files

Change output filenames to hash generated names (on build phase)

output: {
    path: '/',
    filename: '[hash].js',
    chunkFilename: '[chunkhash].js',
},

From that point your foo.js and chunk.1.js will be called like e883ce503b831d4dde09.js and f900ab84da3ad9bd39cc.js. Worth mention that generation of this files are often related to making production and time too update cacheBust value.

2. How to include not known names of files?

Since now your foo.js - main file is named in not known way. To extract this name of file you can use AssetsPlugin

const AssetsPlugin = require('assets-webpack-plugin');
const assetsPluginInstance = new AssetsPlugin();

and add this plugin to webpack.config.js

plugins: [
    assetsPluginInstance
]

In webpack-assets.json file you should see something like

{
    "main": {
        "js": "/e883ce503b831d4dde09.js"
    }
}

You can use this file to point to main .js file. For more details read this answer

3. Benefit time

I guess that if you make app production because of modification of chunk.2.js file, you change files paths from

- build.js?cacheBust=12345
- chunk.1.js?cacheBust=12345
- chunk.2.js?cacheBust=12345
- chunk.2.js?cacheBust=12345

to new ones

- build.js?cacheBust=12346   // modified referation to chunk.2.js file
- chunk.1.js?cacheBust=12346
- chunk.2.js?cacheBust=12346 // modified
- chunk.2.js?cacheBust=12346

If you would use above solution you will get free cache determination. Now filles will be called like

(previous production)

- e883ce503b831d4dde09.js
- f900ab84da3ad9bd39cc.js
- 5015cc82c7831915903f.js
- 8b6de52a46dd942a63a7.js

(new production)

- c56322911935a8c9af13.js // modified referation to chunk.2.js file
- f900ab84da3ad9bd39cc.js
- cd2229826373edd7f3bc.js // modified
- 8b6de52a46dd942a63a7.js

Now only main file and chunk.2.js names are changed and you will get this for free by using webpack way.

You can read more about long term caching here https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31




回答3:


You can use HtmlWebpackPlugin

Description from webpack.js.org/plugins/html-webpack-plugin:

... plugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation...

Part of my webpack.config.js:

// ...
const HtmlWebpackPlugin = require('html-webpack-plugin');
// ...
module.exports = {
   // ...
   plugins: [
      new HtmlWebpackPlugin({
         template: './assets/index.html',
         hash: true,
      }),
      // ...
   ]
};

If hash: true then append a unique webpack compilation hash to all included scripts and CSS files. This is useful for cache busting.

More about HtmlWebpackPlugin options on github.com/jantimon/html-webpack-plugin

Thanks to this option I got output html file with:

<!DOCTYPE html>
<html>
   <head>
      <!-- ... rest of my head code ... -->
      <link href="./css/styles.css?f42fdf96e2f7f678f9da" rel="stylesheet">
   </head>
   <body>
      <!-- ... rest of my body code ... -->
      <script type="text/javascript" src="./js/index.bundle.js?f42fdf96e2f7f678f9da"></script>
   </body>
</html>

Source code of my project: github.com/cichy380/html-starter-bs4-webpack



来源:https://stackoverflow.com/questions/39238163/how-can-i-make-webpack-use-a-cache-busting-suffix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!