是否可以自动生成 HTML5-AppCache Manifest 文件?

Is it possible to auto generate HTML5-AppCache Manifest files?

我正在使用 Angular 4 和 Angular CLI 构建一个网络应用程序。我正在尝试为 IE 浏览器实现 App-cache,因为它不支持服务工作者,但我 运行 遇到的问题是构建生成的文件静态文件有一个与之关联的哈希码,所以我我无法明确列出我要为 App-cache 缓存的文件。有什么办法吗?

有一种方法可以从 angular cli 中的文件名中删除散列。

您可以使用 ng build --prod --output-hashing none

上的输出散列选项删除散列部分
output-hashing --output-hashing (short cut: -oh)
possible values: none, all, media, bundles

控制台输出

xxxx$ ng build --prod --output-hashing none
Date: 2017-09-21T14:52:13.362Z                                                          
Hash: 115fd3ecef82add2dac2
Time: 6415ms
chunk {0} polyfills.bundle.js (polyfills) 64.1 kB {4} [initial] [rendered]
chunk {1} main.bundle.js (main) 5.14 kB {3} [initial] [rendered]
chunk {2} styles.bundle.css (styles) 0 bytes {4} [initial] [rendered]
chunk {3} vendor.bundle.js (vendor) 307 kB [initial] [rendered]
chunk {4} inline.bundle.js (inline) 1.36 kB [entry] [rendered]
xxxx$ ls
README.md       e2e         node_modules        package.json        src         tslint.json
dist            karma.conf.js       package-lock.json   protractor.conf.js  tsconfig.json
xxxx$ cd  dist
xxxx$ ls
3rdpartylicenses.txt    favicon.ico     index.html      inline.bundle.js    main.bundle.js      polyfills.bundle.js styles.bundle.css   vendor.bundle.js
xxxx$ ls -lart
total 784
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users  306976 Sep 21 10:52 vendor.bundle.js
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users       0 Sep 21 10:52 styles.bundle.css
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users   64051 Sep 21 10:52 polyfills.bundle.js
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users    5141 Sep 21 10:52 main.bundle.js
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users    1363 Sep 21 10:52 inline.bundle.js
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users     568 Sep 21 10:52 index.html
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users    5430 Sep 21 10:52 favicon.ico
-rw-r--r--   1 xxxxxx  NASDCORP\Domain Users    3415 Sep 21 10:52 3rdpartylicenses.txt
drwxr-xr-x  17 xxxxxx  NASDCORP\Domain Users     578 Sep 21 10:52 ..
drwxr-xr-x  10 xxxxxx  NASDCORP\Domain Users     340 Sep 21 10:52 .

angular 和 cli 版本:

xxxx$ ng -v
@angular/cli: 1.4.2
node: 8.5.0
os: darwin x64
@angular/animations: 4.4.3
@angular/common: 4.4.3
@angular/compiler: 4.4.3
@angular/core: 4.4.3
@angular/forms: 4.4.3
@angular/http: 4.4.3
@angular/platform-browser: 4.4.3
@angular/platform-browser-dynamic: 4.4.3
@angular/router: 4.4.3
@angular/cli: 1.4.2
@angular/compiler-cli: 4.4.3
@angular/language-service: 4.4.3
typescript: 2.3.4

我不推荐 Aniruddha Das 的回答,因为文件名中的哈希值实际上非常有用:

您在 SW 开发中可能面临的最困难的任务之一是缓存失效,而这个问题正是通过散列文件名解决的。用户浏览器如何知道何时使您的供应商捆绑包失效?浏览器无法知道它有新版本,因为它必须下载 vendor-bundle 才能识别其中的更改。

正是出于这个原因,文件名中的散列被发明出来了。当你更新你的一个依赖项时,vendor-bundle 将在其文件名中生成另一个哈希值,导致浏览器加载新文件 --> 适当的缓存失效!

那么如何实现呢?

我创建了一个小节点脚本,您可以使用它:

let fs = require('fs');
let glob = require('glob');

let getFiles = (filter) => {
    return new Promise(resolve => {
        glob(filter, (err, innerfiles) => {
            resolve(innerfiles);
        });
    });
}

let getAllFiles = (filters) => {
    var promises = [];
    for (var i = 0; i < filters.length; i++) {
        var promise = getFiles(filters[i]);
        promises.push(promise);
    }

    return Promise.all(promises).then(fileArrays => {
        var allFiles = [];

        for (var j = 0; j < fileArrays.length; j++) {
            var fileArray = fileArrays[j];
            allFiles = allFiles.concat(fileArray);
        }

        return allFiles;
    });
}

let writeFile = (fileName, content) => {
    return new Promise(resolve => {
        fs.writeFile(fileName, content, 'utf8', function (err) {
            if (err) return console.log(err);
            resolve();
        });
    });
}

getAllFiles([ "./dist/*.bundle.*", "./dist/assets/*" ]).then(files => {
    var content = `CACHE MANIFEST

CACHE:
`;
    for (var k = 0; k < files.length; k++) {
        var fileName = files[k];
        content += fileName.replace("./dist/", "") + `
`;
    }

    content += `
NETWORK:
*`;

    writeFile("./dist/cache.manifest", content);
});

只需在 package.json:

的脚本部分创建一个新条目

"build:appcache": "node ./createAppCache"

(假设您已经在 package.json 所在的同一目录中创建了一个脚本文件,其中包含我上面发布的名为 "createAppCache.js" 的内容)。

您可以 运行 在您的控制台中输入该脚本:npm 运行 build:appcache