使用Vite构建的包在Next.js中报错:styled.div不是函数
解决Vite构建组件包在Next.js中引入时
styled.div报错问题 报错信息:
Collecting page data .TypeError: styled.div is not a function
at file: dist/org-chart-maker.mjs:3:29
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
Next.js项目内直接使用styled-components正常,但引入Vite构建的组件包时,包内的styled-components被识别为undefined,以下是相关代码与配置:
相关代码与配置
vite.config.ts
import { resolve as pathResolve } from 'node:path'; import { defineConfig } from 'vite'; import tsConfigPaths from 'vite-tsconfig-paths'; import svgr from 'vite-plugin-svgr'; import reactPlugin from '@vitejs/plugin-react'; import { peerDependencies } from './package.json'; export default defineConfig({ plugins: [ tsConfigPaths(), svgr({ exportAsDefault: true, }), reactPlugin({ jsxRuntime: 'classic', }), ], root: pathResolve(__dirname, 'src'), publicDir: pathResolve(__dirname, 'public'), build: { outDir: pathResolve(__dirname, 'dist'), emptyOutDir: true, copyPublicDir: false, sourcemap: true, minify: false, target: ['esnext'], lib: { entry: pathResolve(__dirname, 'src', 'index.ts'), formats: ['es', 'cjs'], }, rollupOptions: { external: [...Object.keys(peerDependencies)], output: { interop: 'auto', globals: { react: 'React', 'react-dom': 'ReactDOM', 'styled-components': 'styled', }, }, }, }, });
组件代码
import styled from 'styled-components'; const StyledDiv = styled.div``; const Test = () => <StyledDiv>hello</StyledDiv>; export default Test;
构建输出(org-chart-maker.js)
"use strict"; const React = require("react"); const styled = require("styled-components"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const React__default = /* @__PURE__ */ _interopDefault(React); const styled__default = /* @__PURE__ */ _interopDefault(styled); const StyledDiv = styled__default.default.div``; const Test = () => /* @__PURE__ */ React__default.default.createElement(StyledDiv, null, "hello"); module.exports = Test; //# sourceMappingURL=org-chart-maker.js.map
构建输出(org-chart-maker.mjs)
import React from "react"; import styled from "styled-components"; const StyledDiv = styled.div``; const Test = () => /* @__PURE__ */ React.createElement(StyledDiv, null, "hello"); export { Test as default }; //# sourceMappingURL=org-chart-maker.mjs.map
问题原因与解决方法
核心问题是ES模块下styled-components的默认导出处理异常。在.mjs输出中,直接使用import styled from "styled-components"无法正确获取到styled的实例对象,导致styled.div调用失败。
方案1:调整组件代码的导入方式
显式处理默认导出,确保拿到正确的styled实例:
import styled from 'styled-components'; // 兼容ES模块和CommonJS的导出结构 const actualStyled = styled.default || styled; const StyledDiv = actualStyled.div``; const Test = () => <StyledDiv>hello</StyledDiv>; export default Test;
方案2:优化Vite的Rollup配置
修改rollupOptions中的interop和exports配置,强制兼容不同模块规范的导出:
rollupOptions: { external: [...Object.keys(peerDependencies)], output: { interop: 'compat', // 替换auto为compat,加强导出兼容性 exports: 'named', globals: { react: 'React', 'react-dom': 'ReactDOM', 'styled-components': 'styled', }, }, },
方案3:完善package.json的导出映射
明确指定ES模块和CommonJS模块的入口,避免Next.js解析错误:
{ "exports": { ".": { "import": "./dist/org-chart-maker.mjs", "require": "./dist/org-chart-maker.js" } }, "type": "module" }
方案4:开启Next.js的styled-components编译支持
在next.config.js中启用内置的styled-components编译器,确保SSR和模块解析正常:
const nextConfig = { compiler: { styledComponents: true, }, }; module.exports = nextConfig;
验证效果
重新构建组件包,更新Next.js项目中的依赖后,styled.div即可正常调用,不再抛出错误。
内容的提问来源于stack exchange,提问作者webjay
相关产品推荐
相关产品推荐

