service-worker - 如何修改 Workbox 生成的预缓存 list 文件?需要 url 前面有 '/'

标签 service-worker progressive-web-apps workbox workbox-webpack-plugin

在生成的 precache-manifest.*.js当我需要绝对路径时,将所有引用的 URL 归档,因为我的应用程序也会有一些子目录。

生成文件示例:

self.__precacheManifest = (self.__precacheManifest || []).concat([
  {
    "revision": "1d94d834b7044ec6d4e9",
    "url": "js/app.js"
  },
  {
    "revision": "632f09e6ed606bbed1f1",
    "url": "css/app.css"
  },
  ...
}

当我需要它看起来像这样时:

self.__precacheManifest = (self.__precacheManifest || []).concat([
  {
    "revision": "1d94d834b7044ec6d4e9",
    "url": "/js/app.js"
  },
  {
    "revision": "632f09e6ed606bbed1f1",
    "url": "/css/app.css"
  },
  ...
}

我正在使用 webpack 4.41.0 和 workbox-webpack-plugin 4.3.1

任何帮助将不胜感激!如果需要,我也可以添加更多细节。

这是我的 webpack 配置:

let config = {
  entry,

  stats: {
    hash: false,
    version: false,
    timings: false,
    children: false,
    errorDetails: false,
    entrypoints: false,
    performance: inProduction,
    chunks: false,
    modules: false,
    reasons: false,
    source: false,
    publicPath: false,
    builtAt: false
  },

  performance: { hints: false },

  // Valid options: "production" | "development" | "none"
  mode: inProduction ? 'production' : 'development',

  plugins: [
    new CopyPlugin(copyConfig),
    new webpack.ProvidePlugin(providers), // Providers, e.g. jQuery
    new WebpackNotifierPlugin({ title: 'Webpack' }), // OS notification
    new VueLoaderPlugin(), // Vue-loader
    new CleanWebpackPlugin(pathsToClean, cleanOptions), // Clean up pre-compile time
    new ManifestPlugin(manifestOptions), // Manifest file
    new FriendlyErrorsWebpackPlugin({ clearConsole: true }), // Prettify console
    new MiniCssExtractPlugin(cssOptions), // Extract CSS files
    new WebpackMd5Hash(), // use md5 for hashing
    {
      /* Laravel Spark RTL support */
      apply: (compiler) => {
        compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
          exec('node_modules/rtlcss/bin/rtlcss.js public/css/app-rtl.css ./public/css/app-rtl.css', (err, stdout, stderr) => {
            if (stdout) process.stdout.write(stdout);
            if (stderr) process.stderr.write(stderr);
          });
        });
      }
    }
  ],

  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ['vue-loader']
      },
      {
        test: /\.s?css$/,
        use: [
          'style-loader',
          {
            loader: MiniCssExtractPlugin.loader,
            options: { hmr: isHot } // set HMR if flagged
          },
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.json', '.vue'],
    modules: ['node_modules'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '~': path.join(__dirname, 'resources/assets/js'),
      jquery: "jquery/src/jquery",
    }
  },

  output: {
    filename: 'js/[name].js',
    // chunkFilename: inProduction ? 'js/[name].[chunkhash].js' : 'js/[name].js',
    path: publicPath,
  },

  optimization: {
    ...optimization,
    concatenateModules: false,
    providedExports: false,
    usedExports: false,
  },

  devtool: inDevelopment ? 'eval-source-map' : false,

  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    port: port,
    contentBase: publicPath,
    historyApiFallback: true,
    noInfo: false,
    compress: true,
    quiet: true,
    hot: isHot,
  }
}

还有我的 GenerateSW:

new GenerateSW({
    // The cache ID
    cacheId: 'pwa',

    // The path and filename of the service worker file that will be created by the build process, relative to the webpack output directory.
    swDest: path.join(publicPath, 'sw.js'),

    clientsClaim: true,
    skipWaiting: true,

    // Files to exclude from the precache
    exclude: [/\.(?:png|jpg|jpeg|svg)$/, /\.map$/, /manifest\.json$/, /service-worker\.js$/, /sw\.js$/],

    // Default fall-back url
    navigateFallback: '/',

    // An optional array of regular expressions that restricts which URLs the configured navigateFallback behavior applies to.
    // This is useful if only a subset of your site's URLs should be treated as being part of a Single Page App.
    navigateFallbackWhitelist: [
      /^\/media\//,
      /^\/settings\//,
    ],

    // Runtime cache
    runtimeCaching: [
      {
        urlPattern: new RegExp(`${process.env.APP_URL}`),
        handler: 'NetworkFirst',
        options: {
          cacheName: `${process.env.APP_NAME}-${process.env.APP_ENV}`
        }
      },
      {
        urlPattern: new RegExp('https://fonts.(googleapis|gstatic).com'),
        handler: 'CacheFirst',
        options: {
          cacheName: 'google-fonts'
        }
      }
    ]
  }
)

还有几个定义的公共(public)变量:

...
// Production flag
const inProduction = process.env.NODE_ENV === 'production'
const inDevelopment = process.env.NODE_ENV === 'development'

// HMR
const isHot = process.argv.includes('--hot')

// Public/webroot path
const publicPath = path.resolve(__dirname, 'public')

// Primary webpack entry point(s)
const entry = {
  /*
   * JS entry point/Vue base component
   * Make sure to import your css files here, e.g. `import '../sass/app.scss'`
   */
  app: path.resolve(__dirname, 'resources/assets/js/app.js'),
}
...

最佳答案

对于任何访问此问题的人,您可以使用 webpack output.publicPath 设置为您的 list URLS 添加前缀,如下所示:

plugins: [
    new InjectManifest({}) // Left here just for reference
],
output: {
    publicPath: '/' // You can add your prefix here
}

关于service-worker - 如何修改 Workbox 生成的预缓存 list 文件?需要 url 前面有 '/',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58103531/

相关文章:

service-worker - ServiceWorker 未收到提取请求

javascript - 即使在加载新版本后,Service Worker 仍可能显示旧版本应用程序的情况?

javascript - 如何使用javascript检测移动设备屏幕是否关闭

audio - 在渐进式 Web 应用程序中使用系统的敲击声

javascript - 使用工作箱运行时缓存,请求不会显示在 chrome 的缓存存储中

javascript - Workbox 似乎没有从 webpack 构建中预先缓存 block

javascript - 如果我实现网络推送通知,我的个人网站是否需要隐私政策?

IOS 12 PWA 支持

javascript - service-worker `onupdatefound` 未在移动设备上触发

reactjs - 如何将其他文件添加到 CRA WorkBox Precache?