Rik*_*oid 5 koa service-worker next.js
在我的项目中,我使用 NextJS+KOA+Apollo。我的 nextJS 应用程序位于根目录中的客户端内。我正在使用 next-offline 将其转换为 PWA。
Nextjs 应用程序位于客户端目录中。koa 服务器在服务器目录中。
当我通过以下命令构建应用程序时:
next build client && tsc --project tsconfig.server.json
Run Code Online (Sandbox Code Playgroud)
它在客户端内部为 nextjs 创建了一个构建目录,并在顶层为 koa 服务器创建了 dist 目录。
我通过以下命令在生产中运行代码
NODE_ENV=production node dist/server/index.js
Run Code Online (Sandbox Code Playgroud)
问题 Service Worker 正在正确注册。但我收到以下错误:
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)
Run Code Online (Sandbox Code Playgroud)
下面是我生成的构建文件:
tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist",
"target": "es2017",
"isolatedModules": false,
"noEmit": false
},
"include": ["server/**/*.ts"]
}
Run Code Online (Sandbox Code Playgroud)
下面是我的 next.config.js(在客户端目录中)
/* 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,
);
Run Code Online (Sandbox Code Playgroud)
下面是我启动 koa 服务器的文件
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 });
Run Code Online (Sandbox Code Playgroud)
================================================== ==============
我现在做了一个肮脏的修复。我不确定如何正确处理它。如果有人能对此发表意见,我将不胜感激。
作为bo.svg,firfox.svg,所有这些静态文件都在我的文件中抛出404,Ex - (/_next/bo.svg?WB_REVISION=e02afe0476bb357aebde18136fda06e0)以启动koa服务器,添加了检查此URL并提供静态文件的条件从构建目录如下:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
它现在符合我的目的,但不确定如何正确处理。
| 归档时间: |
|
| 查看次数: |
1731 次 |
| 最近记录: |