我按照下面的步骤在下一个js中实现了模块联合。
1.在src/node/components文件夹中的存储库cm-insurance-web中创建一个组件Insurance_Detail.tsx,该组件将被公开。下面是next.config.js文件。
const assetPrefix = '/jobs-assets';
const nextConfig = {
assetPrefix,
env: {
assetPrefix
},
experimental: {
images: {
unoptimized: true
}
},
reactStrictMode: true,
webpack5: true,
srcDir: 'src/node/',
//distDir: 'build',
webpack: (config, options) => { // webpack configurations
config.plugins.push(
new options.webpack.container.ModuleFederationPlugin({
name:"InsuranceA",
filename: "static/chunks/pages/cm_insurance_web.js", // remote file name which will used later
remoteType: "var",
exposes: { // expose all component here.
**"./InsuranceDetail": "./components/Insurance_Details.tsx"**
},
shared: [
{
react: {
eager: true,
singleton: true,
requiredVersion: false,
}
},
{
"react-dom": {
eager: true,
singleton: true,
requiredVersion: false,
}
},
]
})
)
config.cache = false;
config.output.publicPath = 'http://localhost:3000/_next/';
return config
}
}
module.exports = nextConfig
1.当我们使用命令npm run build构建repo cm-insurance-web时,我们可以看到在src/node/.next/static/chunks/pages/cm_insurance_web.js中创建了javascript文件。这个项目repo在localhost上的3000端口上运行。
1.现在需要在其他存储库中使用这个javascript,比如cm-job-board-web。让我们创建消费者应用程序。下面是它的next.config.js文件
/** @type {import('next').NextConfig} */
const assetPrefix = '/jobs-assets';
const path = require('path');
const nextConfig = {
assetPrefix,
env: {
assetPrefix
},
basePath: '/search-jobs',
experimental: {
images: {
unoptimized: true
}
},
reactStrictMode: true,
srcDir: 'src/node/',
webpack: (config, options) => {
config.plugins.push(
new options.webpack.container.ModuleFederationPlugin({
name:"jobboardWeb",
filename: "static/chunks/cm_job_board_web.js",
remoteType: "var",
remotes: {
InsuranceA: JSON.stringify('InsuranceA@http://localhost:3000/jobs-assets/_next/static/chunks/pages/cm_insurance_web.js')
},exposes: {},
shared: [
{
react: {
eager: true,
singleton: true,
requiredVersion: false,
}
},
{
"react-dom": {
eager: true,
singleton: true,
requiredVersion: false,
}
},
]
})
)
config.cache = false;
return config
},
webpack5: true
}
module.exports = nextConfig
1.在消费者应用的_app.tsx文件中添加脚本标签,如下所示:
import { AppProps } from "next/app";
import "bootstrap/dist/css/bootstrap.css";
import "../styles/globals.scss";
import Layout from "../components/layout";
import { persistor, store } from "../store/store";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import Authentication from "../config/auth.gaurd";
import Head from "next/head";
import React from "react";
import Script from "next/script";
function MyApp({ Component, pageProps }: AppProps) {
return (
<Layout>
<>
<Script src="http://localhost:3000/jobs-assets/_next/static/chunks/pages/cm_insurance_web.js" />
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@100;200;300;400;500;600;700&display=swap"/>
<link rel="shortcut icon" href="/favicon2.ico"/>
<title>Jobboard Search</title>
</Head>
<Script id="gtm-script" strategy="afterInteractive">
{`(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-TKJH8RR');`
}
</Script>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Authentication>
<noscript dangerouslySetInnerHTML={{ __html:
`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-TKJH8RR"
height="0" width="0" style="display:none;visibility:hidden"></iframe>
`}}>
</noscript>
<Component {...pageProps} />
</Authentication>
</PersistGate>
</Provider>
</>
</Layout>
);
}
export default MyApp;
1.让我们将该模块导入index.tsx文件并使用它。
import {NextPage} from "next";
import React, {lazy, Suspense, useState} from "react";
import dynamic from 'next/dynamic'
const InsuranceDetail2 = dynamic(() => import(('InsuranceA/InsuranceDetail')), {
ssr: false
}) as NextPage;
const Insurance: NextPage = ({}: any) => {
return (
<InsuranceDetail2 />
)
}
export default Insurance
在完成上述步骤后,我可以看到远程js文件正在浏览器的网络选项卡中加载,但远程组件没有呈现并获得空白页面。
Please find attached screenshot
请让我知道,如果我错过了什么在这里。我采取了参考从下面的链接。
2条答案
按热度按时间0g0grzrc1#
这是一个快速变化的软件包,所以信息很快就会过时,并且非常特定于您正在使用的版本。但是在快速浏览您的配置之后,我会建议您做一些事情。我假设您使用的是nextjs-mf软件包的版本6。
1.我不认为你需要在共享配置中React。
remoteType: "var"
是不必要的1.设置文件名为
"static/chunks/remoteEntry.js"
1.你可能想在额外的选项中设置
automaticAsyncBoundary: true
如果您正在主机中获取远程条目文件,那么这意味着您的网络配置或多或少配置良好。如果组件没有呈现,你可以试着检查你正在公开的组件或模块的远程入口文件。看看它是否存在。如果存在,你应该确保格式正确(esm或commonjs).如果你正在连接两个nextjs应用程序,它应该以最小的干预工作,所以删除远程类型设置.让插件做这件事。
像这样配置你的遥控器:
8iwquhpp2#
安装nextjs-mf️注意:要使用Module Federation功能,您需要访问[https://app.privjs.com/package?pkg=@module-federation/nextjs-mfnextjs-ssr^(https://app.privjs.com/package?pkg=@module-federation/nextjs-mf%5B%5Bnextjs-ssr%5E%5D)插件,该插件目前需要付费许可证!
要安装该工具,我们需要使用npm登录到[PrivJs}(https://privjs.com/ ^),为此,运行以下命令:
npm login --registry https://r.privjs.com
完成此操作后,包含您的凭据的文件将保存在~/. npmrc中。现在您可以使用以下命令安装nextjs-mf:
npm install @module-federation/nextjs-mf --registry https://r.privjs.com
所以模块联邦是下一个js中的付费模块,在付费模块的帮助下,我能够实现它。
1.保险模块的next.config.js。
1.在package.json中添加模块联邦的依赖。
1.在同一保险模块的_app.tsx文件中添加导入。
这就是expose组件
1.现在,在next.config.js中更新远程组件(消费者应用程序- cm-job-board-web)
1.在消费者app的package.json中添加模块联合的依赖。
1.在消费者应用的_app.tsx文件中添加导入。
1.最后将该模块导入index.tsx文件并在消费者应用程序中使用它。
就是这样。