我正在尝试使用存储库中从自定义 UI 库导入的组件。两者都使用相同的堆栈(React、Typescript、Styled Components)以及使用 Next.js 的 Web 应用程序。运行时
npm run dev
我收到此错误:
⨯ TypeError: styled_components__WEBPACK_IMPORTED_MODULE_1__ is not a function
at eval (webpack-internal:///./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.style.js:35:22)
at ./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.style.js (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\vendor-chunks\@test.js:90:1)
at __webpack_require__ (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.jsx:7:74)
at ./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.jsx (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\vendor-chunks\@test.js:20:1)
at __webpack_require__ (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///./node_modules/@test/test-ui/dist/components/CtaButton/index.js:2:68)
at ./node_modules/@test/test-ui/dist/components/CtaButton/index.js (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\vendor-chunks\@test.js:100:1)
at __webpack_require__ (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///./node_modules/@test/test-ui/dist/components/index.js:2:68)
at ./node_modules/@test/test-ui/dist/components/index.js (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\vendor-chunks\@test.js:170:1)
at __webpack_require__ (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///./node_modules/@test/test-ui/dist/index.js:2:69)
at ./node_modules/@test/test-ui/dist/index.js (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\vendor-chunks\@test.js:240:1)
at __webpack_require__ (C:\Users\Josh\Everything\Files\projects\work\test\test\.next\server\webpack-runtime.js:33:42) {
page: '/'
}
我的下一个配置:
const nextConfig = {
transpilePackages: ["@test/test-ui"],
output: "export",
reactStrictMode: true,
compiler: {
styledComponents: true,
},
};
export default nextConfig;
要分发 UI 库,我使用以下命令:
rm -rf dist && npx tsc && npx tsc-alias
这是 TS 配置:
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"target": "ES2020",
"allowJs": false,
"skipLibCheck": true,
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"strictBindCallApply": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"declaration": true,
"outDir": "dist",
"sourceMap": true,
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": [
"node_modules",
"src/**/*.test.ts",
"src/**/*.test.tsx",
"src/**/*.stories.ts",
"src/**/*.stories.tsx"
]
}
长话短说,我只是将 TS/TSX 文件与声明文件一起编译成
dist/
。
似乎没有任何关于此的文档。我见过的大多数解决方案都包含 Babel,但是这些解决方案似乎已经过时,因为 Next.js 将其默认编译器移至 SWC。此外,之前有一个用于转译包的库,但现在已集成在 Next 配置中。
我所知道的是,我收到错误没有在下一个配置中设置
transpilePackages
属性:
⨯ ./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.jsx
Module parse failed: Unexpected token (4:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this
file. See https://webpack.js.org/concepts#loaders
| import { ButtonTheme } from "./types";
| export function CtaButton({ text, href, onClick, theme = ButtonTheme.Light, }) {
> return (<CtaButtonBox href={href} onClick={onClick} $buttonTheme={theme}>
| <ButtonText>{text}</ButtonText>
| <ArrowSvg />
Import trace for requested module:
./node_modules/@test/test-ui/dist/components/CtaButton/CtaButton.jsx
./node_modules/@test/test-ui/dist/components/CtaButton/index.js
./node_modules/@test/test-ui/dist/components/index.js
./node_modules/@test/test-ui/dist/index.js
添加
transpilePackages
属性可以解决这个问题,这是有道理的,所以我相信这会缩小到我的构建过程或 Webpack/Next 配置问题。我尝试过独立使用 Babel、SWC 和 Rollup 来解决这个问题,但似乎没有一个配置可以做到这一点。我见过一个 Babel 插件可以解决样式组件的some问题,但它对这个特定问题不起作用
当然,发布此内容后不久我就找到了解决方案。当我注意到样式组件部分中的免责声明时,我发现自己正在查看Next.js编译器文档,希望能收集到一些关于我可以调整的Webpack/SWC配置选项的信息:
注意:minify、transpileTemplateLiterals 和 pure 尚未实现。您可以在此处关注进度。 ssr 和 displayName 转换是在 Next.js 中使用样式组件的主要要求。
我之前没有听说过
transpileTemplateLiterals
选项,所以我立即希望这能解决我的问题。快速尝试表明情况并非如此。
然后我访问了该注释中链接的 Github 问题并随意滚动浏览评论,并没有真正看到任何有用的东西。有一些关于默认导出不适用于样式组件的争论,但它似乎不太相关。事实证明这是关键,并且该问题中的最后评论让我尝试一下:
可以确认 import { styled } from 'styled-components';现在也按预期工作。 (已测试 Next.js 14.0.4-canary.41) 谢谢@kdy1! 🙌
事实证明,将 UI 库中的所有导入从
import styled from "styled-components"
更新为 import { styled } from "styled-components"
完全解决了问题。