feat(portal-shell): add MSW mock layer with production bundle exclusion (P1-5)
MSW v2.7.0 fallback layer covering dashboard/users/exams/grades domains. NEXT_PUBLIC_MSW=1 enables browser Service Worker + SSR route handler mock responses without backend. Production build excludes all mock data via Turbopack resolveAlias redirecting @/mocks to empty stub. Acceptance: build bundle (client+server) verified clean of mock strings; typecheck/lint/vitest (231 tests) all pass.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Next.js 配置(v2.1 M8 + v0.2 Tailwind v4 + Next 16 Turbopack + P1-4 next-intl)
|
||||
* Next.js 配置(v2.1 M8 + v0.2 Tailwind v4 + Next 16 Turbopack + P1-4 next-intl + P1-5 MSW)
|
||||
*
|
||||
* 角色:插件化仪表盘宿主(单 Next.js App Router · 单 Docker)
|
||||
* - output:standalone(单容器部署)
|
||||
@@ -7,17 +7,32 @@
|
||||
* - 反向代理:/api/v1/* → api-gateway :8080(JWT 校验 + 注入 x-user-id/x-user-role)
|
||||
* - GraphQL 查询走 apollo-router :3000(M8 验收点,由 Apollo Client 直连)
|
||||
* - next-intl:无 i18n 路由模式(locale 由 cookie 决定,ARCHITECTURE.md §3.4 V3-A6)
|
||||
* - MSW 兜底层(P1-5):NEXT_PUBLIC_MSW!=1 时把 @/mocks 与 @/mocks/graphql-data
|
||||
* 重定向到空 stub,确保生产 bundle 不含 mock 数据(ARCHITECTURE.md §3.4 V3-A7)
|
||||
*
|
||||
* Next 16 默认 Turbopack:
|
||||
* - turbopack.resolveExtensions 处理 ESM 包 .js 后缀导入源码 TS 文件的映射
|
||||
* - webpack 配置保留作为 fallback(--webpack flag 时生效)
|
||||
*
|
||||
* 关联:portal-shell ARCHITECTURE.md §3.4 V3-A6、spec §2、project_rules §3.2
|
||||
* 关联:portal-shell ARCHITECTURE.md §3.4 V3-A6/V3-A7、spec §2、project_rules §3.2
|
||||
*/
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import createNextIntlPlugin from "next-intl/plugin";
|
||||
|
||||
const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts");
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// P1-5:MSW 启用开关。生产构建(NEXT_PUBLIC_MSW 非等于 "1")时把
|
||||
// @/mocks 与 @/mocks/graphql-data 重定向到空 stub,
|
||||
// 确保 bundle 不含真实 mock 数据与 msw 包。
|
||||
// 注意:Turbopack resolveAlias 不支持 Windows 绝对路径("windows imports
|
||||
// are not implemented yet"),故使用 @/mocks/empty 说明符(由 tsconfig
|
||||
// paths 解析为 src/mocks/empty.ts),而非绝对路径。
|
||||
const MSW_ENABLED = process.env.NEXT_PUBLIC_MSW === "1";
|
||||
const MOCKS_STUB_SPECIFIER = "@/mocks/empty";
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
@@ -43,6 +58,17 @@ const nextConfig = {
|
||||
".cjs",
|
||||
".json",
|
||||
],
|
||||
// P1-5:MSW 关闭时把 @/mocks(MswProvider 静态 import)与
|
||||
// @/mocks/graphql-data(route.ts 静态 import)重定向到空 stub。
|
||||
// 使用 @/mocks/empty 说明符作为目标(Turbopack 不支持 Windows 绝对路径)。
|
||||
...(MSW_ENABLED
|
||||
? {}
|
||||
: {
|
||||
resolveAlias: {
|
||||
"@/mocks": MOCKS_STUB_SPECIFIER,
|
||||
"@/mocks/graphql-data": MOCKS_STUB_SPECIFIER,
|
||||
},
|
||||
}),
|
||||
},
|
||||
// Webpack 配置(fallback,使用 --webpack flag 时生效)
|
||||
webpack(config) {
|
||||
@@ -51,6 +77,16 @@ const nextConfig = {
|
||||
...config.resolve.extensionAlias,
|
||||
".js": [".ts", ".tsx", ".js"],
|
||||
};
|
||||
// P1-5:MSW 关闭时把 @/mocks 与 @/mocks/graphql-data 重定向到空 stub。
|
||||
// webpack resolve.alias 支持 exact 匹配($ 后缀)与前缀匹配,
|
||||
// 这里用 exact 匹配避免误伤其他 @/mocks/xxx 路径(实际只有这两个 import 点)。
|
||||
if (!MSW_ENABLED) {
|
||||
config.resolve.alias = {
|
||||
...config.resolve.alias,
|
||||
"@/mocks$": MOCKS_STUB_SPECIFIER,
|
||||
"@/mocks/graphql-data$": MOCKS_STUB_SPECIFIER,
|
||||
};
|
||||
}
|
||||
return config;
|
||||
},
|
||||
async rewrites() {
|
||||
|
||||
Reference in New Issue
Block a user