webpack 将WorkBox添加到NX工作区中的angular应用程序

tquggr8v  于 2023-10-19  发布在  Webpack
关注(0)|答案(1)|浏览(134)

我试图在我的应用程序中切换ServiceWorker,从@angular/service-worker切换到workbox,但我发现文档中缺乏好的示例。我知道这是一个框架无关的工具,但构建似乎有点麻烦。有没有一种更简单的方法来做这件事?还是我在遵循最佳实践?
我有以下结构:

  1. apps
  2. myApp
  3. sw.ts My Workbox SW template
  4. tsconfig.workbox.json Only needed because of my extra webpack build step
  5. webpack.config.js Config of the extra build step
  6. workbox-build.js Config for the workbox-cli when injecting
  7. project.json NX version of the angular cli config
  8. dist
  9. apps
  10. myApp

sw.ts

  1. import { clientsClaim, skipWaiting } from 'workbox-core';
  2. import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
  3. declare const self: ServiceWorkerGlobalScope;
  4. skipWaiting();
  5. clientsClaim();
  6. cleanupOutdatedCaches();
  7. precacheAndRoute(self.__WB_MANIFEST); // Will be filled in build time

tsconfig.workbox.json:

  1. {
  2. "compilerOptions": {
  3. "typeRoots": ["./typings"],
  4. "module": "esnext",
  5. "moduleResolution": "node",
  6. "importHelpers": true,
  7. "target": "es2015",
  8. "lib": ["esnext", "webworker"]
  9. },
  10. "files": ["./sw.ts"]
  11. }

webpack.config.json:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'production',
  4. output: {
  5. path: path.resolve(__dirname, '../../dist/apps/myApp'),
  6. filename: 'sw.js',
  7. },
  8. module: {
  9. rules: [
  10. {
  11. test: /\.ts$/,
  12. loader: 'ts-loader',
  13. options: { configFile: 'tsconfig.workbox.json' },
  14. },
  15. ],
  16. },
  17. resolve: { extensions: ['.js', '.ts'] },
  18. };

workbox-build.js:

  1. const { injectManifest } = require('workbox-build');
  2. const workboxConfig = {
  3. globDirectory: 'dist/apps/myApp',
  4. globPatterns: ['**/*.{css,eot,html,ico,jpg,js,json,png,svg,ttf,txt,webmanifest,woff,woff2,webm,xml}'],
  5. globFollow: true, // follow symlinks
  6. globStrict: true, // fail on error
  7. globIgnores: [
  8. `**/*-es5.js*`,
  9. 'sw.js',
  10. ],
  11. // Allows to avoid using cache busting for Angular files because Angular already takes care of that!
  12. dontCacheBustURLsMatching: new RegExp('.+.[a-f0-9]{20}..+'),
  13. maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10MB
  14. swSrc: 'dist/apps/myApp/sw.js',
  15. swDest: 'dist/apps/myApp/sw.js',
  16. };
  17. // Calling the method and output the result
  18. injectManifest(workboxConfig).then(({ count, size }) => {
  19. console.log(`Generated ${workboxConfig.swDest},
  20. which will precache ${count} files, ${size} bytes.`);
  21. });

在我的package.json中有一个脚本:

  1. "build:wb": "webpack ./apps/myApp/sw.ts --config ./apps/myApp/webpack.config.js && node ./apps/myApp/workbox-build.js"

这要执行两个任务1)编译sw.ts,2)将静态资源作为预缓存注入到编译后的sw.js中。但我认为这是一个混乱的解决方案。
Angular已经使用webpack构建了,我不能使用自定义的webpack配置将这个构建过程集成到我的project.json中吗?它真的必须是一个额外的构建步骤,这是手动启动后,角是完成建设?
我想我在这里认为可能的是,在我的project.json文件中引用一个自定义的webpack配置,这是在Angular 构建管道的最后一步执行的。webpack配置将首先编译我的sw.ts,然后从angular构建中收集静态文件,将这些文件的预缓存注入到编译后的sw.ts中,并将结果输出到dist文件夹中,与其余的angular编译一起沿着。
这将消除对一个额外的tsconfig文件和一个单独的构建脚本的需要,并使整个构建更容易理解。

pbpqsu0x

pbpqsu0x1#

实际上使用自定义webpack解决了这个问题:

projects.json:

  1. {
  2. ...
  3. "targets": {
  4. "build": {
  5. "executor": "@angular-builders/custom-webpack:browser",
  6. "options": {
  7. "customWebpackConfig": {
  8. "path": "apps/myApp/webpack.config.js",
  9. "replaceDuplicatePlugins": true
  10. },
  11. ...
  12. },
  13. ...
  14. },
  15. "serve": {
  16. "executor": "@angular-builders/custom-webpack:dev-server",
  17. ...
  18. }
  19. }
  20. }

webpack.config.js:

  1. const path = require('path');
  2. const { InjectManifest } = require('workbox-webpack-plugin');
  3. const CopyPlugin = require('copy-webpack-plugin');
  4. const AngularWebpackPlugin = require('@ngtools/webpack').AngularWebpackPlugin;
  5. module.exports = {
  6. plugins: [
  7. // Required to get InjectManifest to precache assets, since this webpack config
  8. // apparently runs before angular copies assets to dist.
  9. new CopyPlugin({
  10. patterns: [
  11. {
  12. context: 'apps/myApp/src/assets',
  13. from: '**/*',
  14. to: './assets',
  15. }
  16. ],
  17. }),
  18. new InjectManifest({
  19. swSrc: path.resolve(__dirname, './src/sw.ts'),
  20. swDest: path.resolve(__dirname, '../../dist/apps/myApp/sw.js'),
  21. // Allows the plugin to compile the sw.ts file
  22. compileSrc: true,
  23. // Without this, Webpack yields an error.
  24. webpackCompilationPlugins: [
  25. // The only reason for having a separate tsconfig here, is to add
  26. // a different `files` array. If I include the sw.ts file in the main
  27. // tsconfig, angular complains a lot.
  28. new AngularWebpackPlugin({ tsconfig: 'apps/myApp/tsconfig.wb.json' }),
  29. ],
  30. exclude: [/\-es5.js$/, /sw.js/],
  31. maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10MB
  32. }),
  33. ],
  34. };

现在我可以运行nx build myApp,它构建了所有内容,包括服务工作者!
我很乐意接受其他的答案,如果有人可以改进这一点。

展开查看全部

相关问题