I have created a react (TS) using babel webpack. It is working fine. Now I am converting it to a PWA. I followed this webpack article to updated webpack.config.js. To register the service worker, instead of doing it in index.html, I created a service-worker.tsx and referencing it in index.tsx.
I am getting this error
service-worker.ts:22 Uncaught ReferenceError: process is not defined at register (service-worker.ts:22:33) at eval (index.tsx:14:60) at ./src/index.tsx (main.js:219:1) at webpack_require (main.js:253:41) at main.js:322:37 at main.js:324:12
I have added 3 files, where I changed the configuration to integrate workbox, for registering and un registering.
webpack.config.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 (error at export default function register)
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();
});
}
}
index.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()
CodePudding user response:
After a little bit of research I found out that I needed to update the webpack.config.js with the following process definitions. It was not a problem of export as I was initially thinking. In my service worker I am using process.env entities.
In fact you can add other process.env parameters, I got my information from this article and this stackoverflow
CodePudding user response:
In the webpack.config.js add the following:
const webpack = require("webpack");
const processEnvPlugin = new webpack.DefinePlugin({"process.env.PUBLIC_URL": JSON.stringify(process.env.PUBLIC_URL)});
plugins: [htmlWebPackPlugin, workBoxPlugin_Generate, processEnvPlugin]