'MonoRepo Next Js with PWA Service worker do not meet the installability with custom webpack and server settings

I am getting two issues due to which the PWA application is not able to run correctly

1.)Writing down custom server code with if case to handle sw.js

2.)Adding Webpack in next. config

Sample code for testing the issue.

https://github.com/parmarravi/MonoRepoPWANextJs

THIS WORKS Both Shared and PWA

next.config.js

const withTM = require("next-transpile-modules")(["shared"]);
const withPWA = require("next-pwa");

module.exports = withPWA(
  withTM({
    pwa: {
      dest: "public",
      register: true,
      skipWaiting: false,
      fallbacks: {
        image: "/static/images/fallback.png",
      },
    },
  })
);

server.js

const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const { join } = require("path");

const dev = process.env.NODE_ENV !== "production";
const hostname = "localhost";
const port = 8081;
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
  createServer(async (req, res) => {
    const parsedUrl = parse(req.url, true);
    const { pathname } = parsedUrl;
    console.log(`>> ${pathname}`);
    handle(req, res, parsedUrl);
  }).listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://${hostname}:${port}`);
  });
});

THIS DOES NOT WORK

Adding condition to handle SW.js does not able to render PWA install on chrome.

Error:

localhost/:1 Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8081/') with script ('http://localhost:8081/sw.js'): A bad HTTP response code (404) was received when fetching the script.

server.js

const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const { join } = require("path");

const dev = process.env.NODE_ENV !== "production";
const hostname = "localhost";
const port = 8081;
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
  createServer(async (req, res) => {
    const parsedUrl = parse(req.url, true);
    const { pathname } = parsedUrl;
    console.log(`>> ${pathname}`);
     if (
       pathname === "/sw.js" ||
       /^\/(workbox|worker|fallback)-\w+\.js$/.test(pathname)
     ) {
       const filePath = join(__dirname, "_next", pathname);
       app.serveStatic(req, res, filePath);
     } else {
       handle(req, res, parsedUrl);
     }
  }).listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://${hostname}:${port}`);
  });
});

Adding Webpack with PWA does not work

Build Error

[PWA] Auto register service worker with: /Users/raviparmar/Desktop/Work/REACT/next-pwa/node_module> [PWA] Service worker: /Users/raviparmar/Desktop/> [PWA] Fallback to precache routes when fetch faiValidationError: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.

  • configuration.module.rules[6] should be one of these: ["..." | object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use? }, ...] -> A rule.
    Details:
    • configuration.module.rules[6].use.options should be one of these: string | object { … } -> Options passed to a loader. Details:
      • configuration.module.rules[6].use.options should be a string.
      • configuration.module.rules[6].use.options should be an object: object { … } at validate (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/compiled/schema-utils3/index.js:1:150822) at validateSchema (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/compiled/webpack/bundle5.js:131217:2) at create (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/compiled/webpack/bundle5.js:134714:24) at webpack (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/compiled/webpack/bundle5.js:134761:32) at Object.f [as webpack] (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/compiled/webpack/bundle5.js:89273:16) at /Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/build/compiler.js:31:40 at new Promise () at Object.runCompiler (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/build/compiler.js:30:12) at /Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/build/index.js:369:59 at Span.traceAsyncFn (/Users/raviparmar/Desktop/Work/REACT/next-pwa/node_modules/next/dist/trace/trace.js:79:26) { errors: [ { keyword: 'oneOf', dataPath: '.module.rules', schemaPath: '#/properties/rules/oneOf', params: [Object], message: 'should match exactly one schema in oneOf', schema: [Array], parentSchema: [Object], data: [Array], children: [Array] } ],
module.exports = withPWA(
  withTM({
    pwa: {
      dest: "public",
      register: true,
      skipWaiting: false,
      fallbacks: {
        image: "/static/images/fallback.png",
      },
    },
 webpack: (config, options) => {
      config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf)$/,
        use: {
          loader: "url-loader",
          options: 100000,
          name: "[name].[ext]",
        },
      });
      return config;
    },
  })
);

NOR this works


module.exports = withTM(
  withPWA({
    webpack: (config, options) => {
      config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf)$/,
        use: {
          loader: "url-loader",
          options: 100000,
          name: "[name].[ext]",
        },
        pwa: {
          dest: "public",
          register: true,
          skipWaiting: false,
          fallbacks: {
            image: "/static/images/fallback.png",
          },
        },
      });
      return config;
    },
  })
);



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source