Home > OS >  Uncaught ReferenceError: process is not defined error when converting react (TS) app to PWA with web
Uncaught ReferenceError: process is not defined error when converting react (TS) app to PWA with web

Time:06-27

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]
  • Related