【问题标题】:Angular service worker with webpack (without CLI)带有 webpack 的 Angular 服务工作者(没有 CLI)
【发布时间】:2018-01-26 13:29:49
【问题描述】:

我有一个使用 webpack 构建的非常大的 Angular 项目(我正在使用 Microsoft 的 ASP.NET 核心模板)。有什么方法可以使用@angular/service-worker?

我已经尝试添加包并导入它,但服务工作者永远不会构建。没有错误,但我什么也没得到。使用该标志构建的新 CLI 项目按预期工作。

【问题讨论】:

    标签: angular webpack


    【解决方案1】:

    我也在为此苦苦挣扎,因为我没有使用 CLI。我设法通过将这些脚本包含在 npm 脚本中来使其工作。

        "ngsw-config": "node_modules/.bin/ngsw-config dist src/ngsw-config.json",
        "ngsw-copy": "cp node_modules/@angular/service-worker/ngsw-worker.js dist/",
        "build-ngsw": "npm run ngsw-config && npm run ngsw-copy"
    

    在您的生产构建脚本中包含“build-ngsw”。

    第一个脚本通过读取 ngsw-config.json(您必须创建)在您的 dist 文件夹中创建 ngsw.json 文件。第二个脚本将实际的 Angular Service Worker 从 @angular/service-worker 复制到 dist 文件夹。

    导入并注册 service worker。请参阅本教程中的步骤 3 Angular Service Worker Getting Started

    【讨论】:

      【解决方案2】:

      对于使用 webpack 构建的非 cli 项目,您可能根本不需要使用 Angular Service Worker。 Workbox 是生成服务工作者的好库,它有一个不错的 webpack 插件。

      npm install --save-dev workbox-webpack-plugin
      

      webpack.config:

      import { GenerateSW } from 'workbox-webpack-plugin'
      // const {GenerateSW} = require('workbox-webpack-plugin')
      

      默认情况下,它会生成服务工作线程来预缓存你的 webpack 输出

      plugins: [
          // other webpack plugins
          new GenerateSW()
      ]
      

      然后,您可以在引导您的 Angular 应用程序后安装这个生成的服务工作者,例如:

      platformBrowserDynamic().bootstrapModule(AppModule).then(() => {
      
          if( !('serviceWorker' in navigator) ){
              console.warn('Too bad, Service worker is not supported in current browser')
              return
          }
      
          window.navigator.serviceWorker
              .register(`/service-worker.js`, { scope: '/' })
              .then(registration => console.log(`Service worker registration succeeded`))
              .catch(error => console.log(`Service worker registration failed`))  
      })
      

      前提是你的服务器从 webpack 的 publicPath 提供服务。对于更复杂的场景,请参考它的文档:workbox-webpack-plugin,但是,让我在这里强调一些常见的场景:

      我。预缓存非 webpack 资产

      如果你想预缓存非 webpack 管理的资产,使用globDirectoryglobPatterns 选项来查找它们,如下所示:

      new GenerateSW({
           globDirectory: '.',
           globPatterns: ['assets/**/*.{svg, png}']
      })
      

      生成的 glob 资产 url(您可以在 service-worker.jsself.__precacheManifest 中找到)将针对 glob 目录进行解析,这意味着您的服务器应该服务于 /assets/

      二。预缓存服务器生成的资产

      您的 index.html 可能是服务器生成的,这种情况很常见,在这种情况下,您可能希望使用 templatedUrl 来指定要预缓存的路由以及如何修改检索到的资产。这很方便与 navigateFallback 一起使用,以确保我们在访问非预缓存路由时优雅地回退到我们的 index.html。

      new GenerateSW({
          globDirectory: '.',
          globPatterns: [],
          templatedUrls: {
              '/': ['templates/Index.html']
          }
          navigateFallback: '/'
      })
      

      templateUrl 指定要预缓存的路由和 glob-pattern 以查找将用于修改从该 URL 检索到的响应的资源。确保您指定了globDirectory,否则插件将失败并出现令人困惑的错误。正如workbox/issues/763 中提到的,指定文件的 md5 哈希将用于修订检索到的资产,只要/templates/Index.html 没有变化,这将是有效的。通常,如果您使用HtmlWebpackPlugin 将您的捆绑包(带哈希) 注入Index.html 模板,service-worker.js 预缓存清单修订将根据需要更改。

      三。在运行时缓存 API 响应

      您可能还经常想要缓存一些 API 响应,比如说出现在您网站的动态内容中的用户个人资料图标。在这种情况下,我们可以为我们的 API 使用网络优先策略以始终从网络获取(如果可用)和配置文件图标的缓存优先策略,例如:

      new GenerateSW({
          runtimeCaching: [{
              urlPattern: /^http[s]*:\/{2}[\w.:-]+\/api\//,
              handler: 'networkFirst'
          }, {
              urlPattern: /^http[s]*:\/{2}[\w.:-]+\/profile_icons\//,
              handler: 'cacheFirst'
          }]
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-10
        • 2018-01-02
        • 1970-01-01
        • 2019-11-07
        • 1970-01-01
        • 2017-01-20
        相关资源
        最近更新 更多