如何在Rollup.js中进行缓存破坏?

7
我的项目中,我需要进行缓存清除,因为在新的部署之后,浏览器通常只会重新加载HTML而不是JS和CSS文件。
目前,我没有以任何方式构建HTML,它只是已经存在于公共目录中。
最简单的方法似乎是在JS引用中添加时间戳:
<script type="module" src="bundle/index.js?ts=20201026-102300"></script>

现在,在已经使用rollup.js的项目中,实现这一点的最佳方法是什么?
我看过@rollup/plugin-html,但是它文档中的示例让我感到困惑,因为它以JS文件作为输入:
 input: 'src/index.js',

这应该是哪个JS文件?

我认为需要定义:

  • 一个输入的HTML文件
  • 一些用于设置时间戳变量的代码空间
  • 一个输出的HTML文件

那么最好的方法是什么,可以使用@rollup/plugin-html或其他方法吗?

2个回答

0

我自己也在寻找这个问题的答案,经过一些正则表达式的摆弄,几分钟后我终于解决了它。

注意:这个解决方案每次构建时都会编辑你的 HTML 文件。没有输入(模板)HTML 和输出 HTML。

  1. 安装rollup-plugin-replace-html-vars插件

npm install rollup-plugin-replace-html-vars --save-dev

  1. 将以下配置添加到你的rollup.config.js文件中
// rollup.config.js
// ...
plugins: [
    replaceHtmlVars({
        files: '**/index.html',
        from: /\.\/\w+\/\w+\.\w+.\w+\?v=\d+/g,
        to: './dist/app.min.js?v=' + Date.now(),
    }),
]


在你的 index.html 文件中,添加对 app.js 的引用:
<script type="module" src="./dist/app.min.js?v=1630086943272"></script>
  1. 运行Rollup,每次运行时index.html中对app.js的引用将具有构建时间戳。

奖励:

如果您的文件名中没有.min,请改用此正则表达式:

/\.\/\w+\/\w+\.\w+\?v=\d+/g

全面披露;我不是正则表达式专家,只是设法将它们拼凑在一起。我敢打赌这里的某个人会有更好的方法来使用正则表达式捕获./dist/app.min.js?v=1630086943272,但这对我的解决方案有效。


你还需要在顶部添加 import replaceHtmlVars from 'rollup-plugin-replace-html-vars'; - thdoan
是的,我假设如果有人正在使用ES6和Rollup,他们知道函数需要被导入。 - Robin van Baalen

0

我选择使用文件哈希值,这意味着只有当文件有新版本时才会重新加载。 为此,我编写了自己的实用工具:

function escapeStringRegexp(string) {
    if (typeof string !== 'string') {
        throw new TypeError('Expected a string');
    }

    return string
        .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
        .replace(/-/g, '\\x2d');
}

function insertHashToFile(options) {
    return {
        writeBundle(outputOptions) {
            const outputDir = outputOptions.dir ? outputOptions.dir : path.dirname(outputOptions.file);
            let indexHtml = fs.readFileSync(options.htmlFile, 'utf8');

            for (const sourceFile of options.sourceFiles) {
                const fb = fs.readFileSync(path.join(outputDir, sourceFile));
                const hash = crypto.createHash('sha1');
                hash.update(fb)
                const hexHash = hash.digest('hex');

                const replacePattern = new RegExp(escapeStringRegexp(sourceFile) + '(:?\\?h=[^"]+)?', 'g');
                indexHtml = indexHtml.replaceAll(replacePattern, `${sourceFile}?h=${hexHash.substring(0, 8)}`);
            }

            fs.writeFileSync(options.htmlFile, indexHtml);
        },
    };
}

然后

plugins: [
    production && insertHashToFile({
        sourceFiles: [
            "bundle.js",
            "bundle.css",
        ],
        htmlFile: "public/index.html",
    }),
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接