'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 |
|---|
