Next.js的微观前端路由问题
我正在使用三个下一个项目(App1,app2,base)建立一个微观前端框架。 App1
和App2
是远程应用程序,base
是主机应用程序。
app1 next.config.js
:
const { withModuleFederation } = require('@module-federation/nextjs-mf');
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
mergeRuntime: true,
name: 'app1',
library: {
type: config.output.libraryTarget,
name: 'app1',
},
filename: 'static/runtime/app1RemoteEntry.js',
remotes: {},
exposes: {
'./thanatos': './components/thanatos',
},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
if (!isServer) {
config.output.publicPath = 'http://localhost:3001/_next/';
}
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
app2 next.config.js
const { withModuleFederation } = require('@module-federation/nextjs-mf');
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
mergeRuntime: true,
name: 'app2',
library: {
type: config.output.libraryTarget,
name: 'app2',
},
filename: 'static/runtime/app2RemoteEntry.js',
remotes: {},
exposes: {
'./zagreus': './components/zagreus',
},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
if (!isServer) {
config.output.publicPath = 'http://localhost:3002/_next/';
}
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
base next.config.js
const { withModuleFederation } = require('@module-federation/nextjs-mf');
const path = require('path');
// For SSR, resolve to disk path (or you can use code streaming if you have access)
// in production use the chunks
const ssrRemoteEntry = (app) =>
process.env.NODE_ENV === 'production'
? path.join(
`<remotes-path>/${app}/.next/server/chunks/static/runtime/remoteEntry.js`
)
: path.resolve(
__dirname,
`../${app}/.next/server/static/runtime/remoteEntry.js`
);
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
name: 'base',
library: {
type: config.output.libraryTarget,
name: 'base',
},
remotes: {
app1: isServer ? ssrRemoteEntry('app1') : 'app1',
app2: isServer ? ssrRemoteEntry('app2') : 'app2',
},
exposes: {},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
base _document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<script src="http://localhost:3001/_next/static/runtime/app1RemoteEntry.js" />
<script src="http://localhost:3002/_next/static/runtime/app2RemoteEntry.js" />
<Head>
<link rel="icon" href="/favicon.ico" />
<meta
name="description"
content="Demo for Microfrontends using Module Federation"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
当我运行三个应用程序时,base
应用程序我只能看到base
的页面,但是当我单击其他两个按钮时,要导航到app1
和app2
,浏览器显示空白页。
I am building a micro frontend framework with three Next.js projects (app1, app2, base). app1
and app2
are the remote application and base
is the host application.
app1 next.config.js
:
const { withModuleFederation } = require('@module-federation/nextjs-mf');
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
mergeRuntime: true,
name: 'app1',
library: {
type: config.output.libraryTarget,
name: 'app1',
},
filename: 'static/runtime/app1RemoteEntry.js',
remotes: {},
exposes: {
'./thanatos': './components/thanatos',
},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
if (!isServer) {
config.output.publicPath = 'http://localhost:3001/_next/';
}
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
app2 next.config.js
const { withModuleFederation } = require('@module-federation/nextjs-mf');
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
mergeRuntime: true,
name: 'app2',
library: {
type: config.output.libraryTarget,
name: 'app2',
},
filename: 'static/runtime/app2RemoteEntry.js',
remotes: {},
exposes: {
'./zagreus': './components/zagreus',
},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
if (!isServer) {
config.output.publicPath = 'http://localhost:3002/_next/';
}
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
base next.config.js
const { withModuleFederation } = require('@module-federation/nextjs-mf');
const path = require('path');
// For SSR, resolve to disk path (or you can use code streaming if you have access)
// in production use the chunks
const ssrRemoteEntry = (app) =>
process.env.NODE_ENV === 'production'
? path.join(
`<remotes-path>/${app}/.next/server/chunks/static/runtime/remoteEntry.js`
)
: path.resolve(
__dirname,
`../${app}/.next/server/static/runtime/remoteEntry.js`
);
module.exports = {
webpack5: true,
images: {
domains: ['static.wikia.nocookie.net'],
},
webpack: (config, options) => {
const { isServer } = options;
const mfConf = {
name: 'base',
library: {
type: config.output.libraryTarget,
name: 'base',
},
remotes: {
app1: isServer ? ssrRemoteEntry('app1') : 'app1',
app2: isServer ? ssrRemoteEntry('app2') : 'app2',
},
exposes: {},
};
config.cache = false;
withModuleFederation(config, options, mfConf);
return config;
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config;
},
};
base _document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<script src="http://localhost:3001/_next/static/runtime/app1RemoteEntry.js" />
<script src="http://localhost:3002/_next/static/runtime/app2RemoteEntry.js" />
<Head>
<link rel="icon" href="/favicon.ico" />
<meta
name="description"
content="Demo for Microfrontends using Module Federation"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
When I run the three applications, on base
application I can only see the page for base
but when I click on the other two buttons want to navigate to app1
and app2
, the browser shows the blank page.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我可能有解决方案。您需要在Next.config.js中执行的操作是将您的URL添加到.env文件中。从那里,您告诉基本应用程序导航到URL和路线。
这是我所做的事情的示例:
棘手的部分是回到您的基地。这是App1的Next.config.js的示例:
注意WebPackDevmiddleware只是为了令人耳目一新。如果您不想要的话,您不需要它。
I may have the solution for you. What you need to do in the next.config.js is add your URLs to your .env file. From there, you tell your base app to navigate to the URL and route.
Here is a sample of what I have done:
The tricky part is getting back to your base. Here is a sample for App1's next.config.js:
Note the webpackDevMiddleware is just for hot refreshing. You don't need it if you don't want.