当前讨论的范围为主子应用都为nextjs。
此文档作为调研的一部分总结,有很多没考虑的点希望大家指出。
背景
在对项目进行模块拆分时也希望对一些web服务进行拆分。
比如一些独立的应用可以通过微前端的形式部署在主应用下。
有开发联调的成本也有隔离后独立部署的便利,看大家的取舍。
假设有两个web项目(知识库和一个主应用)
qiankun
子应用下需要设置webpack的配置
const nextConfig = {
// assetPrefix: process.env.ASSET_PREFIX || '', // 子应用的资源路径,
// reactStrictMode: true,
// swcMinify: true,
// crossOrigin: 'anonymous',
webpack: (config) => {
config.output.library = `${packageName}-[name]`;
config.output.libraryTarget = 'umd';
config.output.chunkLoadingGlobal = `webpackJsonp_${packageName}`;
return config;
},
}
其中设置libraryTarget会导致子应用启动报错。
关于这一点基本就不考虑qiankun了
还有一点是nextjs下如何设置qiankun的生命周期也暂时没找到方案。
然后去看了下single-spa
single-spa
github.com/single-spa/… 提示暂不支持
模块联邦
github.com/module-fede… 这里有具体的例子 github.com/module-fede…
上面给我们演示了next14下应该如何使用
可以看到文件夹组织形式必须是pages/_app
这样会导致nextjs14的一些新的路由特性没法用。
wujie
暂时考虑用wujie
主要是因为不需要对webpack进行配置,
看下主应用的代码:
'use client';
function Home() {
if (typeof window !== 'undefined') {
const degrade =
window.localStorage.getItem('degrade') === 'true' ||
!window.Proxy ||
!window.CustomElementRegistry;
const { setupApp, preloadApp } = WujieReact;
/**
* 配置应用,主要是设置默认配置
* preloadApp、startApp的配置会基于这个配置做覆盖
*/
setupApp({
name: 'knowledge',
url: hostMap('//localhost:4001/'),
exec: true,
fetch: (url: RequestInfo, options: any) => {
return window.fetch(url, { ...options, credentials: 'omit' });
},
plugins,
// prefix: { 'prefix-dialog': '/dialog', 'prefix-location': '/location' },
degrade,
...lifecycle,
} as any);
if (window.localStorage.getItem('preload') !== 'false') {
preloadApp({
name: 'knowledge',
url: '//localhost:4001/',
});
}
}
// ...
}
引入子应用
'use client';
import { usePathname } from 'next/navigation';
import WujieReact from 'wujie-react';
import hostMap from '~/micro/hostmap';
export default function Page() {
const path = usePathname().replace('/knowledge', '').replace('/', '');
const reacturl = hostMap('//localhost:4001/') + path;
const props = {
jump: (name: string) => {
console.log('name::', name);
},
};
return (
<WujieReact
width="100%"
height="100%"
name="knowledge"
url={reacturl}
sync={!path}
props={props}
></WujieReact>
);
}
子应用下配置一下跨域(next.config.mjs)
/** @type {import('next').NextConfig} */
const nextConfig = {
assetPrefix: process.env.ASSET_PREFIX || 'http://localhost:4001', // 子应用的资源路径,
async headers() {
return [
{
source: '/:path*', // 适用所有路由
headers: [
{
key: 'Content-Security-Policy',
value: "frame-ancestors 'self' *;", // 允许 iframe 加载
},
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET,POST,OPTIONS',
},
{
key: 'Access-Control-Allow-Headers',
value: 'Origin, X-Requested-With, Content-Type, Accept',
},
],
},
];
},
};
export default nextConfig;
这样基本就可以实现一个主应用加载子应用了。
所以暂时用wujie在做,但是在nextjs框架+monorepo的背景下对于微前端应该要再思考一下出发点
再收集一些资料结合一些开发实践再总结了。