Open riksphp opened 5 years ago
Hi,
In my project, I am using NextJS+KOA+Apollo. My nextJS app is inside client in root directory.
Nextjs app is inside client
directory. koa server is inside server
directory.
when i am building the app via below command:
next build client && tsc --project tsconfig.server.json
it creates a build
directory inside client for nextjs and dist
directory at the top level for koa server.
i run the code in production via below command
NODE_ENV=production node dist/server/index.js
ISSUE
Service worker is getting registered properly. But I am getting below error:
PrecacheController.mjs:194 Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://my-domain/_next/bo.svg?__WB_REVISION__=e02afe0476bb357aebde18136fda06e0","status":404}] at l.o (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1749) at async Promise.all (index 0) at async l.install (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1221)
Below is my build file that gets generated:
tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist",
"target": "es2017",
"isolatedModules": false,
"noEmit": false
},
"include": ["server/**/*.ts"]
}
Below is my next.config.js (inside client direcotry)
/* eslint-disable @typescript-eslint/no-var-requires */
const withPlugins = require("next-compose-plugins");
const offline = require("next-offline");
const pino = require("next-pino");
const withTypescript = require("@zeit/next-typescript");
const withCSS = require("@zeit/next-css");
const withLess = require("@zeit/next-less");
const Dotenv = require("dotenv-webpack");
const path = require("path");
const _ = require("lodash");
const nextConfig = {
distDir: "build",
webpack(config) {
config.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: "url-loader",
options: {
limit: 100000,
name: "[name].[ext]",
},
},
});
config.plugins.push(
new Dotenv({
path: path.resolve(process.cwd(), ".env"),
systemvars: true,
}),
);
return config;
},
// overwrites values given in the .env file with the current
// process.env value
env: _.omitBy(
{
GRAPHQL_SERVER: process.env.GRAPHQL_SERVER,
},
_.isUndefined,
),
workboxOpts: {
globPatterns: ["static/**/*"],
globDirectory: "client",
runtimeCaching: [
{
urlPattern: /^https?.*/,
handler: "NetworkFirst",
options: {
cacheName: "offlineCache",
expiration: {
maxEntries: 200,
},
},
},
],
},
};
const cssConfig = {
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[local]",
},
};
const lessConfig = cssConfig;
module.exports = withPlugins(
[
[offline],
[pino],
[withTypescript],
[withCSS, cssConfig],
[withLess, lessConfig],
],
nextConfig,
);
And below is my file to start koa server
import Router from "koa-router";
const server = new Koa();
const dev = !["production", "staging"].includes(process.env.NODE_ENV || "");
const app = next({ dir: "./client", dev });
const publicRouter = new Router();
const handle = app.getRequestHandler();
publicRouter.get("/service-worker.js", async ctx => {
const pathname = await join(
__dirname,
"../../../client/build",
"service-worker.js",
);
ctx.body = await app.serveStatic(ctx.req, ctx.res, pathname);
ctx.respond = false;
});
publicRouter.get("*", async ctx => {
if (!ctx.path.match(/graphql/)) {
await handle(ctx.req, ctx.res);
ctx.respond = false;
}
});
server.use(async (ctx, next) => {
ctx.res.statusCode = 200;
await next();
});
server.use(publicRouter.routes()).use(publicRouter.allowedMethods());
server.listen({ port: 3000 });
I have done a dirty fix for now. I am not sure how to handle it properly. I will really appreciate if anyone can put forth their view on this.
As bo.svg, firfox.svg, all these static files are throwing 404, Ex - (/_next/bo.svg?__WB_REVISION__=e02afe0476bb357aebde18136fda06e0) in my file to start koa server, added a condition to check this URL and serve static file from build directory like below:
publicRouter.get("*", async ctx => {
if (ctx.path.match(/\_next/) && ctx.path.match(/\.svg/)) {
const pathname = await join(
__dirname,
"../../../client/build",
ctx.path.replace("_next/", ""),
);
ctx.body = await app.serveStatic(ctx.req, ctx.res, pathname);
ctx.respond = false;
} else if (!ctx.path.match(/graphql/)) {
await handle(ctx.req, ctx.res);
ctx.respond = false;
}
});
It served my prupose for now, but not sure how to handle this properly.
We are using nextjs + next-offline + express.
we had the same problem, and the problem was because workbox-precacher try to get some files from '_next/' directory which the express does not serve them.
I have add two directory for static files to be served by express: one is 'static' and another is '_next' as follow:
app.use('/static', express.static(path.join(__dirname, '/static'))) app.use('/_next', express.static(path.join(__dirname, '/_next')))
*Note: _next
is my distDir.
@khanbaba which version of next-offline are you using?
@khanbaba which version of next-offline are you using?
version 4.0.0
Possibly related: I was getting a 404 for _error.js in development, which caused the service worker installation to fail. The list of files to precache in service-worker.js
included http://localhost:3000/_next/static/development/pages/next/dist/pages/_error.js
, which doesn't exist.
Defining a custom _error.js file in the pages
directory fixed the problem. After that, the service worker no longer included the nonexistent _error.js file above.
This was using Next v9.0.6 and next-offline v5.0.0-beta.4.
yeah @khanbaba could you try out the 5.0.0 beta? It's using a new version of workbox which is what is powering next-offline.
@hanford yes. I have tested next-offline 5.0.0-beta.4. The problem not solved. thanks.
Hitting the same issue when deploying to production (staging). Transitive builds dont seem to have this issue.
Possibly related: I was getting a 404 for _error.js in development, which caused the service worker installation to fail. The list of files to precache in
service-worker.js
includedhttp://localhost:3000/_next/static/development/pages/next/dist/pages/_error.js
, which doesn't exist.Defining a custom _error.js file in the
pages
directory fixed the problem. After that, the service worker no longer included the nonexistent _error.js file above.This was using Next v9.0.6 and next-offline v5.0.0-beta.4.
I created a _error.js page and this kept the error from logging in v5.0.0-beta.9
Don't know if it is the good way to go to but I had the same issue and added precache manifest transformation to workboxOpts
in order to remove unwanted URL prefixes: https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestTransform
Like this:
manifestTransforms: [
// Basic transformation to remove a certain URL:
(originalManifest) => {
const manifest = originalManifest.map(entry => {
entry.url = entry.url.replace(/^\/?_next\/public\//, '');
return entry;
});
// Optionally, set warning messages.
const warnings = [];
return {manifest, warnings};
}
]
I suspect however an initial misconfiguration from my side. Using next-offline 5.0.0-beta.9
looks like transformManifest
is gone now, from next-offline? Also, i have an _error.tsx
and am still getting the error.
Seems like i'm actually getting pre-cache requests for an older build, though i'm not sure how thats possible on Now 2
I have the same problem! I register my serviceWorker perfectly, but if i generate new version, nextjs not get the new version...and broken the page
My Error: Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"http://localhost:3000/autostatic/3Om9AVnlaeKY0VFubP78s/_buildManifest.js","status":404}]
It tries to get the files from autostatic
instead of _next/static
.
Can I somehow change the path?
Setting future.webpack to false
fixed it
@kaaax0815 I have the same issue and I think it's fixable it by adding this next-offline option:
withOffline({
workboxOpts: {
// ...
modifyURLPrefix: { 'autostatic/': '_next/static/' },
}
})
Found it at https://github.com/hanford/next-offline/issues/263#issuecomment-738155607. See if it works for you.
@icflorescu but why does webpack change the behaviour of workbox? Could you please look into #278 ? And do you also have depraction warnings?
🎉 Thanks for taking the time to contribute to next-offline!
It is highly appreciated that you take the time to help improve next-offline. We appreciate it if you would take the time to write up a bug report or feature request.
Sadly, if we don't receive enough information, or the issue/feature request doesn't align well with our roadmap, we might respectfull thank you for your time, and close the issue.
Bug fixes and documentation fixes are welcome.
In the case of a bug report 🐞
Please consider the following items when filing a bug report:
In the case of a feature/component request ✍️
Please consider the following items when filing a feature request:
See the contributing guide for more details.
Respect earns Respect 👏
Please respect our Code of Conduct, in short: