Next.js+Module Federation+Turborepo构建报错:自引用依赖存在未使用导出名
Turborepo+Next.js Module Federation构建报错问题
场景说明
在Turborepo单仓环境下,基于两个Next.js应用实现Module Federation:
- searchapp(模块提供者):暴露搜索模块的远程入口,
next.config.js配置如下:
const { NextFederationPlugin } = require('@module-federation/nextjs-mf'); module.exports = { reactStrictMode: true, transpilePackages: ["ui", "@project/lib", "@project/tailwindconfig"], i18n: { defaultLocale: "en", locales: ["en"], }, images: { domains: ["localhost"], }, async rewrites() { return [ { source: "/api/products/:path*", destination: "https://api.project.com/v1/pages/:p*", }, ]; }, webpack(config, { isServer }) { const federationConfig = { name: 'searchapp', filename: 'static/chunks/remoteEntry.js', exposes: { './search': './components/modules/VFinder/index.tsx', }, shared: require("./package.json").dependencies, } config.plugins.push(new NextFederationPlugin(federationConfig)); return config; }, };
- webapp(模块消费者):引入searchapp的模块,
next.config.js配置如下:
const { NextFederationPlugin } = require('@module-federation/nextjs-mf'); module.exports = { reactStrictMode: true, transpilePackages: ["ui", "@project/lib", "@project/tailwindconfig"], i18n: { defaultLocale: "en", locales: ["en"], }, images: { domains: ["localhost"] }, async rewrites() { return [ { source: "/api/products/:path*", destination: "https://api.project.com/v1/pages/:p*", }, ]; }, webpack(config, { isServer }) { const sharedDependencies = Object.entries(require("./package.json").dependencies).map( ([name, version]) => ({ [name]: { singleton: true, requiredVersion: false }, }) ).reduce((acc, item) => ({ ...acc, ...item }), {}); config.plugins.push( new NextFederationPlugin({ name: 'web', filename: 'static/chunks/webRemoteEntry.js', remotes: { searchapp: `searchapp@http://localhost:3001/_next/static/${ isServer ? 'ssr' : 'chunks' }/remoteEntry.js`, }, shared: sharedDependencies, }) ); return config; }, };
消费组件代码:
import React from "react"; import dynamic from "next/dynamic"; const RemotePage = dynamic(() => // @ts-ignore import("searchapp/search").then((mod) => mod.default), { ssr: true } ); export default function vFinder(props) { return ( <React.Fragment> <RemotePage {...props} /> </React.Fragment> ); }
报错情况
searchapp执行yarn build可正常完成,但webapp执行yarn build时抛出以下错误:
web:build: [nextjs-mf] You are sharing react from the default share scope. This is not necessary and can be removed. web:build: [nextjs-mf] You are sharing react-dom from the default share scope. This is not necessary and can be removed. web:build: (node:31043) [DEP_WEBPACK_MODULE_ID] DeprecationWarning: Module.id: Use new ChunkGraph API web:build: (Use `node --trace-deprecation ...` to show where the warning was created) web:build: Failed to compile. web:build: web:build: ../../node_modules/@module-federation/utilities/src/utils/importDelegatedModule.js web:build: Self-reference dependency has unused export name: This should not happen web:build: web:build: Import trace for requested module: web:build: ../../node_modules/@module-federation/utilities/src/utils/importDelegatedModule.js web:build: ../../node_modules/@module-federation/nextjs-mf/src/default-delegate.js?remote=searchapp@http://localhost:3001/_next/static/ssr/remoteEntry.js web:build: remote searchapp/search web:build: ./components/modules/HeroBanner/index.tsx web:build: ./pages/index.tsx web:build: web:build: ../../node_modules/@module-federation/utilities/src/utils/pure.js web:build: Self-reference dependency has unused export name: This should not happen web:build: web:build: Import trace for requested module: web:build: ../../node_modules/@module-federation/utilities/src/utils/pure.js web:build: ../../node_modules/@module-federation/utilities/src/utils/importDelegatedModule.js web:build: ../../node_modules/@module-federation/nextjs-mf/src/default-delegate.js?remote=searchapp@http://localhost:3001/_next/static/ssr/remoteEntry.js web:build: remote searchapp/search web:build: ./components/modules/HeroBanner/index.tsx web:build: ./pages/index.tsx web:build: web:build: > Build failed because of webpack errors web:build: error Command failed with exit code 1. web:build: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
解决步骤
1. 移除不必要的共享依赖
报错提示明确说明react和react-dom不需要加入共享范围,@module-federation/nextjs-mf会自动处理这两个核心依赖。
- 修改webapp的
next.config.js,生成共享依赖时过滤掉react和react-dom:const sharedDependencies = Object.entries(require("./package.json").dependencies) .filter(([name]) => !['react', 'react-dom'].includes(name)) .map(([name, version]) => ({ [name]: { singleton: true, requiredVersion: false }, })) .reduce((acc, item) => ({ ...acc, ...item }), {}); - 同时修改searchapp的
next.config.js,从共享依赖中删除react和react-dom:const dependencies = require("./package.json").dependencies; delete dependencies.react; delete dependencies.react-dom; const federationConfig = { name: 'searchapp', filename: 'static/chunks/remoteEntry.js', exposes: { './search': './components/modules/VFinder/index.tsx', }, shared: dependencies, }
2. 更新Module Federation相关依赖
如果修改后仍报错,尝试将@module-federation/nextjs-mf和@module-federation/utilities升级到最新稳定版本,这类自引用依赖报错大多是旧版本的已知bug。
3. 确认远程入口地址有效性
确保webapp中配置的remote地址在构建阶段可访问,或者改用环境变量区分开发/生产环境的地址,避免硬编码localhost导致的路径问题。
内容的提问来源于stack exchange,提问作者raj dhanani
相关产品推荐
相关产品推荐

