使用esbuild时@emotion/styled报错:import_styled11.default.div不是函数
我用esbuild、React和emotion/MUI搭建站点,其他功能都正常,只有@emotion/styled组件无法工作,抛出错误:uncaught TypeError: import_styled11.default.div is not a function。这种写法在我之前的webpack、Remix、Gatsby项目里都能正常运行,所以问题应该出在esbuild配置上。我知道2021年esbuild的自动JSX运行时变更,但觉得这不是根源,可能漏了某些配置项。我不想依赖Babel或Webpack解决,因为esbuild构建速度比Webpack快太多(当前构建约15秒,Webpack要1分钟以上),请问怎么让@emotion/styled和esbuild兼容?
附相关代码:
Header.tsx
import React, { useState } from "react"; import styled from "@emotion/styled"; import {Box} from "@mui/material"; const Header = () => { return ( <Styles> <Box component="header"> this should be red </Box> </Styles> ); }; const Styles = styled.div` header { background: red; } `; export default Header;
dev-server.cjs(运行命令node dev-server.cjs --watch)
require('esbuild-server') .createServer( { bundle: true, entryPoints: ['src/app.tsx'], watch: true, outfile: "public/bundle.js", define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development') }, jsxImportSource: '@emotion/react', jsxFactory: `jsx`, }, { static: 'public', historyApiFallback: true } ) .start();
ts-config.json
{ "compilerOptions": { "target": "es2018", "jsx": "react-jsx", "jsxImportSource": "@emotion/react", "module": "commonjs", "rootDir": "src", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true } }
问题出在esbuild对@emotion/styled的运行时处理和配置冲突上,以下是具体修复步骤:
修正esbuild的JSX运行时配置
你的配置里已设置jsxImportSource,但缺少jsxRuntime: 'automatic',同时多余的jsxFactory会和自动运行时冲突。修改dev-server.cjs中的esbuild配置:{ bundle: true, entryPoints: ['src/app.tsx'], watch: true, outfile: "public/bundle.js", define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development') }, jsxImportSource: '@emotion/react', jsxRuntime: 'automatic' // 新增配置,启用自动JSX运行时 // 移除原有的jsxFactory配置 }确保emotion包版本兼容
确认@emotion/react和@emotion/styled版本支持esbuild自动JSX运行时(建议版本≥11.7.0),执行命令更新:npm update @emotion/react @emotion/styled验证styled导入方式(可选)
若上述步骤无效,尝试将默认导入改为命名导入,避免模块解析问题:import { styled } from '@emotion/styled';
完成调整后重启dev-server,@emotion/styled即可正常工作。
内容的提问来源于stack exchange,提问作者Luke Brown

