React(CRA)SW缓存“公用”文件夹

Con*_*ard 7 android static-files service-worker create-react-app

在执行create-react-app并启用中的服务后index.js,该src文件夹中的所有相关文件都会被缓存。但是,我的一些资源位于public目录中。当我运行时npm run buildasset-manifest.json并且precache-manifest.HASH.js仅包含HTML,已损坏的JS和CSS(src文件夹中的所有内容)。

如何告诉服务人员从该public文件夹中另外缓存特定文件?

这是实际产生的 precache-manifest.e431838417905ad548a58141f8dc754b.js

self.__precacheManifest = [
  {
    "revision": "cb0ea38f65ed9eddcc91",
    "url": "/grafiti/static/js/runtime~main.cb0ea38f.js"
  },
  {
    "revision": "2c226d1577937984bf58",
    "url": "/grafiti/static/js/main.2c226d15.chunk.js"
  },
  {
    "revision": "c88c70e5f4ff8bea6fac",
    "url": "/grafiti/static/js/2.c88c70e5.chunk.js"
  },
  {
    "revision": "2c226d1577937984bf58",
    "url": "/grafiti/static/css/main.7a6fc926.chunk.css"
  },
  {
    "revision": "980026e33c706b23b041891757cd51be",
    "url": "/grafiti/index.html"
  }
];
Run Code Online (Sandbox Code Playgroud)

但我希望它也包含这些URL的条目:

  • /grafiti/icon-192.png
  • /grafiti/icon-512.png

它们来自public文件夹。

或者:如何以一种可以从Web清单中引用它们的方式manifest.webmanifestsrc文件夹中添加文件图标?

Fab*_*ian 4

我假设您正在寻找一种无需弹出即可工作的解决方案(像我一样)。这种方法对我有用:

  1. 通过安装模块react-app-rewiredyarn add -D react-app-rewired
  2. 替换react-scriptspackage.json 中的 npm 脚本(弹出不需要)

    /* package.json */
    
    "scripts": {
    -   "start": "react-scripts start",
    +   "start": "react-app-rewired start",
    -   "build": "react-scripts build",
    +   "build": "react-app-rewired build",
    -   "test": "react-scripts test --env=jsdom",
    +   "test": "react-app-rewired test --env=jsdom",
        "eject": "react-scripts eject"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建与 package.json 同一级别的 config-overrides.js 文件

我的文件看起来像这样(因为我还想添加一个自己的服务工作线程,为我的 api 添加更复杂的缓存选项),但globPatternsglobDirectory正是您所寻找的。添加此模式后,匹配的文件(在我的例子中为图像、音乐和声音)被添加到生成的 precache-manifest-{hash} 中。

const {InjectManifest} = require('workbox-webpack-plugin');
const path = require('path');

module.exports = {
  webpack: function(config, env) {
    config.plugins.push(
      new InjectManifest({
        globPatterns: [
          'images/*.png',
          'models/*.glb',
          'music/*.mp3',
          'sound/*.mp3'
        ],
        globDirectory: 'build',
        swSrc: path.join('src', 'custom-service-worker.js'),
        swDest: 'service-worker.js'
      })
    );

    return config;
  }
}
Run Code Online (Sandbox Code Playgroud)

PS:如果您需要一个 custom-service.worker.js 文件来使其工作,workbox.precaching.precacheAndRoute([])那么该文件的内容应该足够了,但是工作箱文档对于那些缓存内容也非常有趣