渐进式网页应用 - 使用 Workbox 进行后台同步的 CRA-Typescript PWA?
有人能指引我如何在 CRA-typescript PWA 中使用 Workbox 与 service worker 实现后台同步吗?我已经在网上查找了好几个星期,但仍然没找到好的教程或一步步的指南。
使用 TypeScript 让 service worker 使用 Workbox 是否不可能?
答案#1
Create React App 默认不支持此功能,但你可以通过像 craco 这样的库使其工作,它允许在不 eject 的情况下自定义 create-react-app 配置。
在我的情况下,我能够通过向 CRA 的 webpack 配置中添加额外的插件使其工作。
const path = require('path');
const { InjectManifest } = require('workbox-webpack-plugin');
const { addPlugins } = require('@craco/craco');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
webpack: {
configure: (reactAppConfig) => {
whenProd(() => {
// Technically CRA copies files using fs
// but those are not seen by webpack and InjectMainfest
// I couldn't get those to be included in __WB_MANIFEST
// with the plugin.
// "workbox-build" would work using globPatterns
// but it should be run after CRA has compiled everything
// and it's not clear how to make sure of that
reactAppConfig.plugins = reactAppConfig.plugins.concat([
new CopyPlugin({
patterns: [
{
from: 'public',
to: './',
globOptions: {
dot: false, // ignore hidden files
ignore: [
'*.txt',
'*.map',
],
},
}],
}),
new InjectManifest({
swSrc: path.resolve(__dirname, 'src', 'service-worker', 'my-worker.ts'),
swDest: path.resolve(__dirname, 'build', 'sw.js'), // output js
include: [ // Stuff to include in __WB_MANIFEST
/\.(html|js|css|json)$/,
/static\/.*\.(png|gif|jpg|svg|jpeg)$/
],
exclude: [
/asset-manifest\.json/,
],
maximumFileSizeToCacheInBytes: 2 * 1024 * 1024, // 2 MB
})
]);
});
return reactAppConfig;
},
},
};
您还需要确保您的 TypeScript 工作线程文件使用正确的配置进行编译,您可以通过在工作线程目录中添加 tsconfig.json(例如 src/service-worker/)来实现
{
"compilerOptions": {
"composite": true,
"lib": [
"esnext",
"webworker"
],
},
"include": [
"./**/*.ts"
]
}
并确保你的根 TypeScript 配置指向这个 worker 子项目
{
// .... All the other options
"exclude": [
//...
"./src/service-worker"
],
// point to the service worker subproject
"references": [{ "path": "./src/service-worker" }]
}
请随时指出任何错误。
答案#2
自从 CRA 4.0 发布以来,你可以轻松创建
src/service-worker.js
将文件放在你应用的根文件夹中,它将被 CRA 自动编译。
查看这个
