Reputation: 163
Can someone please point me to the right direction on how to use Workbox with a service worker to implement background syncing in a CRA-typescript PWA? I've been combing the internet for weeks now and still no luck of finding a good tutorial or a step-by-step guide.
Is it impossible to have a service worker use Workbox with Typescript?
Upvotes: 2
Views: 853
Reputation: 68
Since CRA 4.0 was released, you can simple create
src/service-worker.js
file in root folder of your app, and it will automatically compiled by CRA.
Check this
Upvotes: 1
Reputation: 413
Create react app doesn't support this by default however you can get it to work with libraries like craco
which allows to customize create-react-app
configuration without ejecting.
In my case I was able to get it to work by adding an extra plugins to the CRA webpack configuration.
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;
},
},
};
You will also need to make sure your typescript worker file gets compiled with the right configuration, you can do so by adding tsconfig.json
in your worker directory (i.e src/service-worker/
)
{
"compilerOptions": {
"composite": true,
"lib": [
"esnext",
"webworker"
],
},
"include": [
"./**/*.ts"
]
}
And make sure your root typescript conifg points to this worker subproject
{
// .... All the other options
"exclude": [
//...
"./src/service-worker"
],
// point to the service worker subproject
"references": [{ "path": "./src/service-worker" }]
}
Feel free to point out any mistakes.
Upvotes: 2