feat(student-portal): 完整实现 student-portal 微前端
包含 src 全部实现、Dockerfile、配置文件、contracts 包等
This commit is contained in:
99
apps/student-portal/next.config.js
Normal file
99
apps/student-portal/next.config.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user