问题描述
我已决定尝试使用 workBox,但我看到的所有指南都在谈论与 React 生成的 Service Worker 集成。
但是当我安装 CRA 时,我不再为我制作 Service Worker。我需要做什么才能在此处集成工作箱?
这是我当前的代码:
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import swDev from './swDev'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,document.getElementById('root')
);
swDev()
swDev.js
export default function swDev(){
let swURL = `${process.env.PUBLIC_URL}/sw.js`;
if('serviceWorker' in navigator){
navigator.serviceWorker.register(swURL).then(res => {
console.log('Service worker has been registered');
}).catch(err => console.log('Service worker was not registered'))
}
}
那么这是公共文件中的service worker
const cacheVersion = 'v1'
self.addEventListener('install',()=>{
console.log('Service worker has been installed');
})
self.addEventListener('activate',()=>{
console.log('Service worker is being activated');
})
self.addEventListener('fetch',(e)=>{
e.respondWith(handleRequest(e.request))
// function to update the cache
// updateCache(e.request)
})
async function handleRequest(req){
const cache = await caches.open(cacheVersion)
const cacheRes = await cache.match(req)
if(cacheRes){
return cacheRes;
}else{
const netRes = await fetch(req);
console.log(netRes);
if(netRes.ok){
return netRes;
}else{
// return an error message or something by matching it to a 404 page
return netRes;
}
}
}
async function updateCache(req){
if(navigator.onLine){
const res = await fetch(req);
const cache = await caches.open(cacheVersion);
if(res.ok){
// add the response to the caches and return the response
await cache.put(req,res.clone())
}
}
}
解决方法
create-react-app
v4 将在构建时 src/service-worker.js
文件的 check for the presence,如果找到,则运行 workbox-webpack-plugin
的 InjectManifest
plugin,将该文件作为swSrc
参数。
如果您要开始一个新项目并按照 create-react-app
的“Making a Progressive Web App”指南中的说明进行操作,即您运行 npx create-react-app my-app --template cra-template-pwa
,您最终会得到正确的地方。
也就是说您的项目将:
- 自动bundle
src/service-worker.js
中的代码(将 ES 模块导入转换为可以在 Service Worker 内部运行的代码) - 在您的
self.__WB_MANIFEST
内某处查找符号src/service-worker.js
,并将其替换为 precache manifest,其中包含有关您的所有webpack
资产的 URL 和修订信息,以便Workbox 可以预先缓存它们。
如果您对预缓存 webpack
资产不感兴趣,那么您根本不需要使用 InjectManifest
插件,您可以将任何您想要的代码放入名为除 src/service-worker.js
之外的任何内容,并将该文件注册为您的 Service Worker。这取决于你。
如果您对 Workbox 的预缓存感兴趣,但您是从较旧的 create-react-app
升级并且您没有“正确的”src/service-worker.js
文件,您可以手动复制 {{3} } 进入你的项目。