You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Turborepo+Material UI构建React设计系统的问题

解决Turborepo + MUI + Vite关联时的Emotion重复加载与动态Require错误

操作复现

  • 克隆Turborepo设计系统起始仓库后,执行命令安装依赖:
    yarn workspace @acme/core add @mui/material @emotion/react @emotion/styled --dev
    
  • 在acme-core/src创建Button.tsx,重导出MUI组件:
    // Button.tsx
    export { default as Button, type ButtonProps } from '@mui/material/Button'; 
    
  • 更新acme-core/src/index.tsx导出该组件:
    export { Button, type ButtonProps } from './Button';
    
  • 执行yarn dev启动后,Storybook控制台出现警告:
    emotion-react.browser.esm.js:398 You are loading @emotion/react when it is already loaded. Running multiple instances may cause problems. This can happen if multiple versions are used, or if multiple builds of the same version are used.
    
  • 创建新Vite React项目,通过yarn link关联@acme/core,导入组件无TypeScript错误:
    import { Button } from '@acme/core';
    
  • 但应用崩溃,控制台报错:
    index.mjs:12 Uncaught Error: Dynamic require of "react" is not supported
        at index.mjs:12:9
        at ../../node_modules/@emotion/styled/dist/emotion-styled.cjs.dev.js (index.mjs:5938:5)
        at __require2 (index.mjs:18:49)
        at ../../node_modules/@emotion/styled/dist/emotion-styled.cjs.js (index.mjs:6097:24)
        at __require2 (index.mjs:18:49)
        at index.mjs:6555:29
    
  • 修改Button.tsx手动引入React后问题依旧:
    import React from 'react';
    
    import MuiButton, { type ButtonProps as MuiButtonProps } from '@mui/material/Button';
    
    export type ButtonProps = MuiButtonProps;
    
    export function Button(props: ButtonProps) {
      return <MuiButton {...props} />;
    } 
    

解决方案

1. 修复Emotion重复加载问题

Emotion是运行时必需的依赖,不能放在开发依赖中,同时要强制所有工作区使用同一版本:

# 移除开发依赖并重新添加为生产依赖
yarn workspace @acme/core remove @mui/material @emotion/react @emotion/styled --dev
yarn workspace @acme/core add @mui/material @emotion/react @emotion/styled

在Turborepo根目录的package.json中添加resolutions字段,强制依赖版本统一:

"resolutions": {
  "@emotion/react": "^11.11.0",
  "@emotion/styled": "^11.11.0"
}

执行yarn install重新安装依赖。

2. 修复Vite动态Require错误

Vite不兼容CommonJS的动态require语法,需确保@acme/core输出ES模块:
修改packages/acme-core/tsup.config.ts配置:

import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm'], // 仅输出ES模块格式
  dts: true,
  sourcemap: true,
  clean: true,
  external: ['react', 'react-dom'], // 将React标记为外部依赖,避免打包进库
});

重新打包@acme/core:

yarn workspace @acme/core build

同时在Vite项目的vite.config.ts中添加优化配置:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  optimizeDeps: {
    include: ['@acme/core'],
  },
  resolve: {
    alias: {
      // 确保React依赖全局统一
      'react': require.resolve('react'),
      'react-dom': require.resolve('react-dom'),
    },
  },
});

重启Vite项目即可恢复正常。

原因分析

  • Emotion重复加载:误将运行时依赖设为开发依赖,导致宿主项目和@acme/core各自安装了Emotion实例;未统一版本加剧了冲突。
  • 动态Require错误:@acme/core默认打包输出包含CommonJS格式,Vite无法处理其中的动态require语法,转为ES模块输出即可解决。

内容的提问来源于stack exchange,提问作者Ioannis Potouridis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:01:16