原因

因为有个使用ionic框架的项目需要在浏览器上使用,这个项目使用了懒加载(Lazy load),打包出来的js文件是如下图所示这样*.js的文件,这样的话在浏览器里就会存在缓存问题,尤其是微信内置的浏览器这种,导致不能及时刷新缓存。

example

解决方案

知道了原因,也就好解决了,这种情况最好的解决方法就是每次都生成不一样名字的文件,这样的话每次更新后,因为文件名不同,服务器也不会去访问之前的缓存了。

步骤

更改webpack配置

在项目的根目录下找到config文件夹,修改其中的webpack.config.js为以下内容

1
2
3
4
5
6
7
8
9
10
var webpack = require('webpack');
const defaultWebpackConfig = require('../node_modules/@ionic/app-scripts/config/webpack.config.js');

module.exports = function () {
defaultWebpackConfig.prod.output['chunkFilename'] = "[name].[chunkhash:10].js"; // 这个是修改chunk的文件名
defaultWebpackConfig.dev.output['chunkFilename'] = "[name].[chunkhash:10].js"; // 这个是修改chunk的文件名
defaultWebpackConfig.prod.output['filename'] = "[name].[chunkhash:10].js"; // 这个是修改main.js, main.css等文件的文件名
defaultWebpackConfig.dev.output['filename'] = "[name].[chunkhash:10].js"; // 这个是修改main.js, main.css等文件的文件名
return defaultWebpackConfig;
};

更改webpack配置

在package.json中的scripts部分添加webpack配置

1
2
3
"scripts": {
"ionic_webpack": "./config/webpack.config.js"
},

修改引用

修改完webpack的配置以后,重新build之后的文件名已经都加上了hash,如下图所示

example

但是还需要最后一步,需要修改index.html里的文件引用,可以手动做也可以用nodejs来自动化,代码如下(需要安装cheerio和rev-hash)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env node
// This file when run (i.e: npm run postbuild) will add a hash to these files: main.js, main.css, polyfills.js, vendor.js
// and will update index.html so that the script/link tags request those files with their corresponding hashes
// Based upon source: https://gist.github.com/haydenbr/7df417a8678efc404c820c61b6ffdd24
// Don't forget to: chmod 755 scripts/cache-busting.js

var fs = require('fs'),
path = require('path'),
cheerio = require('cheerio'),
revHash = require('rev-hash');

var rootDir = path.resolve(__dirname, '../');
// var wwwRootDir = path.resolve(rootDir, 'platforms', 'browser', 'www');
var wwwRootDir = path.resolve(rootDir, 'www');
var buildDir = path.join(wwwRootDir, 'build');
var indexPath = path.join(wwwRootDir, 'index.html');

var cssPath = path.join(buildDir, 'main.css');
var cssFileHash = revHash(fs.readFileSync(cssPath));
var cssNewFileName = `main.${cssFileHash}.css`;
var cssNewPath = path.join(buildDir, cssNewFileName);
var cssNewRelativePath = path.join('build', cssNewFileName);

var jsPath = path.join(buildDir, 'main.js');
var jsFileHash = revHash(fs.readFileSync(jsPath));
var jsNewFileName = `main.${jsFileHash}.js`;
var jsNewPath = path.join(buildDir, jsNewFileName);
var jsNewRelativePath = path.join('build', jsNewFileName);

var jsPolyfillsPath = path.join(buildDir, 'polyfills.js');
var jsPolyfillsFileHash = revHash(fs.readFileSync(jsPolyfillsPath));
var jsPolyfillsNewFileName = `polyfills.${jsPolyfillsFileHash}.js`;
var jsPolyfillsNewPath = path.join(buildDir, jsPolyfillsNewFileName);
var jsPolyfillsNewRelativePath = path.join('build', jsPolyfillsNewFileName);

var jsVendorPath = path.join(buildDir, 'vendor.js');
var jsVendorFileHash = revHash(fs.readFileSync(jsVendorPath));
var jsVendorNewFileName = `vendor.${jsVendorFileHash}.js`;
var jsVendorNewPath = path.join(buildDir, jsVendorNewFileName);
var jsVendorNewRelativePath = path.join('build', jsVendorNewFileName);

// rename main.css to main.[hash].css
fs.renameSync(cssPath, cssNewPath);

// rename main.js to main.[hash].js
fs.renameSync(jsPath, jsNewPath);

// rename polyfills.js to polyfills.[hash].js
fs.renameSync(jsPolyfillsPath, jsPolyfillsNewPath);

// rename vendor.js to vendor.[hash].js
fs.renameSync(jsVendorPath, jsVendorNewPath);

// update index.html to load main.[hash].css
$ = cheerio.load(fs.readFileSync(indexPath, 'utf-8'));

$('head link[href="build/main.css"]').attr('href', cssNewRelativePath);
$('body script[src="build/main.js"]').attr('src', jsNewRelativePath);
$('body script[src="build/polyfills.js"]').attr('src', jsPolyfillsNewRelativePath);
$('body script[src="build/vendor.js"]').attr('src', jsVendorNewRelativePath);

fs.writeFileSync(indexPath, $.html());

参考

  1. https://forum.ionicframework.com/t/bundled-files-and-cache-busting-lazy-loading/109114
  2. https://gist.github.com/meirmsn/9b37d6c500654b9a487e0c0a72583ef2