我已经使用babel + webpack创建了一个react(TS)。它运行得很好。现在我将它转换为PWA。我跟随这篇webpack文章更新了webpack.config.js。为了注册服务工作者,我创建了一个service-worker.tsx并在index. tsx中引用它,而不是在index.html中注册。
我收到此错误
service-worker.ts:22未捕获引用错误:进程未在以下位置定义:注册表(服务工作者.ts:22:33)评估(索引.tsx:14:60)./src/index.tsx(main.js:219:1)webpack_require(main.js:253:41)在main.js:322:37在main. js:324:12
我已经添加了3个文件,在那里我改变了配置,以集成工作箱,注册和取消注册。
网页包.配置.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const WorkboxPlugin = require("workbox-webpack-plugin");
const path = require("path");
// const htmlPlugin = new HtmlWebPackPlugin({
// template: "./src/index.html",
// filename: "./index.html",
// });
const htmlWebPackPlugin = new HtmlWebPackPlugin({
title: "PWA Webpack Demo",
template: "./src/index.html",
filename: "./index.html",
});
const workBoxPlugin_Generate = new WorkboxPlugin.GenerateSW({
// these options encourage the ServiceWorkers to get in there fast
// and not allow any straggling "old" SWs to hang around
clientsClaim: true,
skipWaiting: true,
});
module.exports = {
entry: "./src/index.tsx",
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
output: {
// NEW
path: path.join(__dirname, "dist"),
filename: "[name].js",
}, // NEW Ends
plugins: [htmlWebPackPlugin, workBoxPlugin_Generate],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: ["ts-loader"],
},
// css rules
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
};
service-worker.tsx(导出默认函数寄存器时出错)
const isLocalhost = Boolean(
window.location.hostname === "localhost" ||
// [::1] is the IPv6 localhost address.
window.location.hostname === "[::1]" ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
),
);
export default function register() {
if ("serviceWorker" in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(
process.env.PUBLIC_URL!,
window.location.toString(),
);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener("load", () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
"This web app is being served cache-first by a service " +
"worker.",
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl: string) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker) {
installingWorker.onstatechange = () => {
if (installingWorker.state === "installed") {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a 'New content is
// available; please refresh.' message in your web app.
console.log("New content is available; please refresh.");
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// 'Content is cached for offline use.' message.
console.log("Content is cached for offline use.");
}
}
};
}
};
})
.catch(error => {
console.error("Error during service worker registration:", error);
});
}
function checkValidServiceWorker(swUrl: string) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get("content-type")!.indexOf("javascript") === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
"No internet connection found. App is running in offline mode.",
);
});
}
export function unregister() {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
索引.tsx
import { createRoot } from 'react-dom/client';
import App from "./app";
//import * as serviceWorker from './serviceWorker';
import registerServiceWorker from './service-worker'
const container = document.getElementById('root')!
const root = createRoot(container)
root.render(<App />)
console.log('Registering service worker', 'Starting...')
registerServiceWorker()
2条答案
按热度按时间5vf7fwbs1#
经过一点研究之后,我发现我需要用下面的过程定义更新webpack.config.js。这不是我最初认为的导出问题。在我的服务工作者中,我使用的是process.env实体。
实际上,您可以添加其他process.env参数,我从这个article和这个stackoverflow中获得了我的信息
hzbexzde2#
在webpack.config.js中添加以下内容: