100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
/**
|
||
* student-portal Next.js 配置(ai14)
|
||
*
|
||
* MF 角色:Remote(name: 'student_app',ARB-002)
|
||
* - 暴露:./StudentApp(学生端完整应用入口)
|
||
* - 复用 Shell 暴露的 singleton:react/react-dom/urql/graphql/@tanstack/react-query 等
|
||
* - 独立壳模式(NEXT_PUBLIC_MF_ENABLED=false):不依赖 Shell,独立渲染
|
||
*
|
||
* 端口:4001(004 §1.2 强制 4 端 4000-4003)
|
||
* 路由:无 /student 前缀(student-portal_contract.md §1.2)
|
||
*/
|
||
|
||
const NextFederationPlugin =
|
||
require('@module-federation/nextjs-mf')?.default;
|
||
|
||
const isMfEnabled = process.env.NEXT_PUBLIC_MF_ENABLED === 'true';
|
||
const shellUrl =
|
||
process.env.NEXT_PUBLIC_SHELL_URL || 'http://localhost:4000';
|
||
|
||
/** @type {import('next').NextConfig} */
|
||
const nextConfig = {
|
||
reactStrictMode: true,
|
||
// ESM 模式:transpilePackages 对齐 NestJS ESM 规范
|
||
transpilePackages: [
|
||
'@edu/ui-components',
|
||
'@edu/ui-tokens',
|
||
'@edu/hooks',
|
||
'@edu/contracts',
|
||
'@edu/shared-ts',
|
||
],
|
||
async rewrites() {
|
||
const gatewayUrl =
|
||
process.env.NEXT_PUBLIC_API_GATEWAY_URL || 'http://localhost:8080';
|
||
return [
|
||
{
|
||
source: '/api/v1/:path*',
|
||
destination: `${gatewayUrl}/api/v1/:path*`,
|
||
},
|
||
{
|
||
source: '/api/auth/:path*',
|
||
destination: `${gatewayUrl}/api/auth/:path*`,
|
||
},
|
||
];
|
||
},
|
||
// 远程类型安全:MF 加载失败不影响独立壳渲染
|
||
webpack(config, { isServer }) {
|
||
// ESM 包使用 .js 后缀导入源码(TS 文件),需映射 .js → .ts
|
||
// 适用于 @edu/hooks 等 ESM 包(type: module + .js 后缀导入)
|
||
// 注意:仅映射 .js,不映射 .mjs(避免破坏 urql 等库的内部解析)
|
||
config.resolve = config.resolve || {};
|
||
config.resolve.extensionAlias = {
|
||
...config.resolve.extensionAlias,
|
||
'.js': ['.ts', '.tsx', '.js'],
|
||
};
|
||
|
||
if (isMfEnabled && NextFederationPlugin) {
|
||
config.plugins.push(
|
||
new NextFederationPlugin({
|
||
name: 'student_app',
|
||
filename: 'static/chunks/remoteEntry.js',
|
||
exposes: {
|
||
'./StudentApp': './src/app/student-app.tsx',
|
||
},
|
||
remotes: {
|
||
teacher: `teacher_app@${shellUrl}/_next/static/chunks/remoteEntry.js`,
|
||
},
|
||
shared: {
|
||
// ARB-002 §2.2:Shell 暴露的 singleton 列表
|
||
react: { singleton: true, requiredVersion: false },
|
||
'react-dom': { singleton: true, requiredVersion: false },
|
||
urql: { singleton: true, requiredVersion: false },
|
||
graphql: { singleton: true, requiredVersion: false },
|
||
'@tanstack/react-query': {
|
||
singleton: true,
|
||
requiredVersion: false,
|
||
},
|
||
zustand: { singleton: true, requiredVersion: false },
|
||
nuqs: { singleton: true, requiredVersion: false },
|
||
'@edu/ui-tokens': { singleton: true, requiredVersion: false },
|
||
'@edu/ui-components': {
|
||
singleton: true,
|
||
requiredVersion: false,
|
||
},
|
||
'@edu/hooks': { singleton: true, requiredVersion: false },
|
||
'@edu/contracts': { singleton: true, requiredVersion: false },
|
||
'@edu/shared-ts': { singleton: true, requiredVersion: false },
|
||
},
|
||
extraOptions: {
|
||
exposeFiles: true,
|
||
enableImageLoaderFix: true,
|
||
},
|
||
}),
|
||
);
|
||
}
|
||
return config;
|
||
},
|
||
};
|
||
|
||
module.exports = nextConfig;
|