From d3f845afc8bb171ff5338ed8751b928b48886f8d Mon Sep 17 00:00:00 2001 From: hardfist Date: Tue, 20 May 2025 14:14:11 +0800 Subject: [PATCH 1/2] feat: throw error when publicPath is function --- src/middleware.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index d920f09..28d2f75 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -18,8 +18,12 @@ function createPublicPathGetter(compiler: Compiler) { const raw = compiler.options.output.publicPath || "/"; if (typeof raw === "function") { - return (compilation?: Compilation) => - compilation ? compilation.getPath(raw) : raw({ hash: "XXXX" }, undefined); + // FIXME: this is a temporary workaround and we may support raw as function in the future + throw new Error( + '"publicPath" cannot be a function in Rspack, which may cause deadlock issue, use string instead', + ); + // return (compilation?: Compilation) => + // compilation ? compilation.getPath(raw) : raw({ hash: "XXXX" }, undefined); } if (/\[(hash|fullhash)[:\]]/.test(raw)) { return (compilation?: Compilation) => From 869857b698bacb099413576a373b78e5f2decd86 Mon Sep 17 00:00:00 2001 From: hardfist Date: Tue, 20 May 2025 14:49:18 +0800 Subject: [PATCH 2/2] chore: remove unused code --- package.json | 9 ++--- pnpm-lock.yaml | 15 ++++---- src/middleware.ts | 91 ----------------------------------------------- 3 files changed, 11 insertions(+), 104 deletions(-) delete mode 100644 src/middleware.ts diff --git a/package.json b/package.json index 7d17618..9a186ae 100644 --- a/package.json +++ b/package.json @@ -89,15 +89,16 @@ "ts-jest": "29.1.2", "typescript": "5.0.2", "wait-for-expect": "^3.0.2", - "webpack": "^5.94.0" + "webpack": "^5.94.0", + "webpack-dev-middleware": "^7.4.2", + "express": "^4.21.2" + }, "dependencies": { "chokidar": "^3.6.0", - "express": "^4.21.2", + "http-proxy-middleware": "^2.0.7", - "mime-types": "^2.1.35", "p-retry": "^6.2.0", - "webpack-dev-middleware": "^7.4.2", "webpack-dev-server": "5.2.0", "ws": "^8.18.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae65ff4..5fbb80c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,21 +14,12 @@ importers: chokidar: specifier: ^3.6.0 version: 3.6.0 - express: - specifier: ^4.21.2 - version: 4.21.2 http-proxy-middleware: specifier: ^2.0.7 version: 2.0.9(@types/express@4.17.21) - mime-types: - specifier: ^2.1.35 - version: 2.1.35 p-retry: specifier: ^6.2.0 version: 6.2.0 - webpack-dev-middleware: - specifier: ^7.4.2 - version: 7.4.2(webpack@5.94.0) webpack-dev-server: specifier: 5.2.0 version: 5.2.0(webpack@5.94.0) @@ -78,6 +69,9 @@ importers: execa: specifier: 9.3.0 version: 9.3.0 + express: + specifier: ^4.21.2 + version: 4.21.2 fs-extra: specifier: 11.2.0 version: 11.2.0 @@ -147,6 +141,9 @@ importers: webpack: specifier: ^5.94.0 version: 5.94.0 + webpack-dev-middleware: + specifier: ^7.4.2 + version: 7.4.2(webpack@5.94.0) packages: diff --git a/src/middleware.ts b/src/middleware.ts deleted file mode 100644 index 28d2f75..0000000 --- a/src/middleware.ts +++ /dev/null @@ -1,91 +0,0 @@ -import crypto from "node:crypto"; -import type { IncomingMessage } from "node:http"; -import { extname } from "node:path"; -import { parse } from "node:url"; -import type { Compilation, Compiler } from "@rspack/core"; -import type { RequestHandler, Response } from "express"; -import mime from "mime-types"; -import type wdm from "webpack-dev-middleware"; - -// biome-ignore lint/suspicious/noExplicitAny: _ -function etag(buf: any) { - const hash = crypto.createHash("sha256").update(buf).digest("hex"); - const etag = hash; - return etag; -} - -function createPublicPathGetter(compiler: Compiler) { - const raw = compiler.options.output.publicPath || "/"; - - if (typeof raw === "function") { - // FIXME: this is a temporary workaround and we may support raw as function in the future - throw new Error( - '"publicPath" cannot be a function in Rspack, which may cause deadlock issue, use string instead', - ); - // return (compilation?: Compilation) => - // compilation ? compilation.getPath(raw) : raw({ hash: "XXXX" }, undefined); - } - if (/\[(hash|fullhash)[:\]]/.test(raw)) { - return (compilation?: Compilation) => - compilation ? compilation.getPath(raw) : `${raw.replace(/\/$/, "")}/`; - } - return () => `${raw.replace(/\/$/, "")}/`; -} - -export function getRspackMemoryAssets( - compiler: Compiler, - rdm: ReturnType, -): RequestHandler { - const getPublicPath = createPublicPathGetter(compiler); - - return (req: IncomingMessage, res: Response, next: () => void) => { - const { method, url } = req; - if (method !== "GET") { - return next(); - } - - // css hmr will append query string, so here need to remove query string - // @ts-expect-error - const path = parse(url).pathname; - const publicPath = getPublicPath(compiler._lastCompilation); - // asset name is not start with /, so path need to slice 1 - // @ts-expect-error - const filename = path.startsWith(publicPath) - ? // @ts-expect-error - path.slice(publicPath.length) - : // @ts-expect-error - path.slice(1); - const buffer = - compiler._lastCompilation?.getAsset(filename) ?? - (() => { - const { index } = rdm.context.options; - const indexValue = - typeof index === "undefined" || typeof index === "boolean" - ? "index.html" - : index; - return compiler._lastCompilation?.getAsset(filename + indexValue); - })(); - if (!buffer) { - return next(); - } - let contentType: string; - if (filename === "") { - contentType = "text/html; charset=utf-8"; - } else { - contentType = - // @ts-expect-error - mime.contentType(extname(path)) || "text/plain; charset=utf-8"; - } - - const calcEtag = etag(buffer); - - const oldEtag = req.headers["if-none-match"]; - res.setHeader("Content-Type", contentType); - res.setHeader("ETag", calcEtag); - if (calcEtag === oldEtag) { - res.status(304).send(); - } else { - res.send(buffer); - } - }; -}