如何将依赖于 Styled Components 的 React 组件库提供给另一个也具有 Styled Comopnents 依赖项的库?
Posted
技术标签:
【中文标题】如何将依赖于 Styled Components 的 React 组件库提供给另一个也具有 Styled Comopnents 依赖项的库?【英文标题】:How to serve a React component library dependent on Styled Components to another library that also has a Styled Comopnents dependency? 【发布时间】:2019-04-06 03:00:40 【问题描述】:我最近将我正在开发的内部组件库转换为样式化组件。该组件库在 package.json 中将 Styled Components 列为 peerDep 和 devDep。从那里我将 Styled Comopnents 导入到每个需要样式的组件中。到目前为止,一切都很好。
我有一个 Create React App (CRA) 应用程序,它也将 Styled Comopnents 作为常规依赖项导入。我需要它才能为这个特定项目构建一次性组件。但是我还需要能够导入我的组件库来为这个基于 CRA 的新应用构建核心组件。
现在这是我的问题:我通过直接链接到 package.json (file:../component-lib
) 中的组件库,在此 CRA 应用程序中测试我最近转换的基于样式化组件的组件库。我已经安装了我的所有部门,从组件库中导入了组件,在 CRA 项目中构建了一个新的项目特定的样式化组件,然后在本地运行它却看到了同样的错误:“看起来有几个 'styled- “我已经阅读了该部分的文档,并学会了不使用 npm 链接并将 SC 作为我的组件库中的 peerDep 和 devDep 服务。
由于我在 CRA 项目中运行多个实例,因此我认为此问题不允许我访问我从组件库传递到自定义 ThemeProvider 的主题道具?
这个问题肯定是因为我缺乏依赖管理方面的知识。我只是想知道是否有其他人遇到过类似的问题,或者我应该怎么做才能避免重复的 Styled Comopnents 实例?
组件库索引
export default as Button from "./components/Button";
export
default as CustomThemeProvider
from "./components/utils/CustomThemeProvider";
组件库 package.json
"scripts":
"build": "nwb build-react-component --copy-files",
"clean": "nwb clean-module && npm clean-demo",
"start": "nwb serve-react-demo",
"lint": "eslint src/**",
"test": "nwb test-react",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build",
"test:coverage": "nwb test-react --coverage",
"test:watch": "nwb test-react --server",
"publish": "npm run build && npm publish"
,
"dependencies":
"@rebass/grid": "^6.0.0-4",
"prop-types": "^15.6.0",
"react-portal": "^4.1.2"
,
"peerDependencies":
"react": "16.x",
"styled-components": "^4.0.3"
,
"devDependencies":
"babel-eslint": "^8.2.2",
"eslint": "^4.18.2",
"eslint-plugin-react": "^7.7.0"
"prettier": "1.14.3",
"nwb": "0.22.x",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-styleguidist": "^7.2.0",
"styled-components": "^4.0.3"
,
组件库 NWB 配置
module.exports =
type: "react-component",
npm:
esModules: false,
umd: false,
,
babel:
stage: 1
;
CRA 项目包.json
"dependencies":
"component-library": "0.16.6",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react-scripts": "2.1.0",
"styled-components": "^4.0.3"
,
【问题讨论】:
请显示您的组件库包的(可能简化的)index.js,也许还有组件库的完整 package.json。我试过你描述的场景没有问题。 我假设你正在使用 webpack 来捆绑你的组件库?我怀疑这是您构建组件库的配置中的某些内容,导致样式组件包含在构建输出中。 继续并在您的问题中包含 nwb.config 内容。 另外,对于您的组件库 package.json,您没有包含脚本部分。我认为这将帮助我了解如何配置 nwb。 使用 nwb 我能够重现您的问题 - 抱怨样式组件的多个实例并且主题似乎无法正常工作。还不确定修复方法。 【参考方案1】:我现在面临同样的问题,但我仍然不确定。我可以正确或不正确地修复它,所以请不要将此答案作为有保证的解决方案。 您可以尝试两件事。
第一个出现在styled-components FAQs 部分中。他们建议使用别名配置 Webpack(我假设您也在使用 Webpack),以便它始终在您指定的任何位置查找 styled-components 依赖项。这应该避免有多个样式组件实例,但到目前为止我无法为我完成这项工作。
第二个选项是使用替代的 no npm link
。显然,当您有符号链接依赖项时(这实际上是 npm link
所做的)。捆绑器的解析器尝试在同一项目中查找依赖项。这也在链接样式组件常见问题部分中提到。
如果您采用这种方法,您应该做的是避免创建一个从 CRA 应用程序指向您的组件库的符号链接,而是复制该文件夹。
有一个名为 wml 的工具可以将组件库的内容复制到 CRA 应用程序的 node_modules
文件夹中。 wml 还能够监视组件库文件夹中的更改,并将更改重新复制到您的 CRA 应用程序的node_modules
。所以,我们可以说 wml 是npm link
的替代品。在我最初的尝试中,它对我来说效果很好,所以也许这是你可以尝试的。
小心:wml 中的an issue 会导致项目中的文件在您第一次设置时被删除。这并没有发生在我身上,但我看到其他人遇到了这个问题,所以如果你打算尝试 wml,请确保你已经将所有更改推送到你的源代码版本控制系统。
这些是使用命令行为项目设置 wml 时需要遵循的步骤:
wml add <component-library-folder> <CRA-app-folder>/node_modules/<name-of-component-library>
wml start
理想情况下,我宁愿在不使用任何外部工具的情况下解决此问题,但如果样式组件维护者在其网站上建议的内容无效,则可以作为一种解决方法。
【讨论】:
【参考方案2】:这只是部分答案,我希望能让您或其他人弄清楚其余部分。我远不是管理这类依赖关系的专家,我正在帮助我加深自己的知识,因为我可能想尽快进行类似的设置。
虽然看起来这应该可以通过 nwb 实现,但我还是直接使用 webpack 以获得更多控制权。即使直接使用 webpack,我也只是做了其中的一部分。当我进行构建时,一切正常,但在 CRA 应用程序的开发模式(npm start)下,styled-components 包仍然被拉入两次,并且样式无法正常工作。这似乎是一个潜在的 webpack 问题,因为开发模式和生产模式的行为如此不同,但它可能与 CRA webpack 开发配置有关,或者(更有可能)是我还不了解的某些方面。
这是一个很好的组件库配置参考示例:https://github.com/kalcifer/webpack-library-example
这是我的测试组件库的 package.json(component-lib3 只是因为尝试了其他几种方法):
"name": "component-lib3",
"version": "1.0.7",
"description": "component-lib3 React component",
"main": "dist/component-lib3.js",
"peerDependencies":
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3"
,
"devDependencies":
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3",
"@babel/core": "^7.1.2",
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.4",
"webpack": "^4.24.0",
"webpack-cli": "^3.1.2"
,
"scripts":
"build": "webpack"
这是 webpack.config.js:
var path = require('path');
module.exports =
entry: './src/index.js',
mode: 'production',
output:
path: path.resolve(__dirname, 'dist'),
filename: 'component-lib3.js',
libraryTarget: 'umd',
library: 'component-lib3'
,
externals:
"styled-components":
commonjs: 'styled-components',
commonjs2: 'styled-components',
amd: 'styled-components'
,
"react":
commonjs: 'react',
commonjs2: 'react',
amd: 'react'
,
"react-dom":
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'react-dom'
,
module:
rules: [
test: /\.js$/,
exclude: /node_modules/,
use:
loader: "babel-loader"
]
;
还有.babelrc:
"presets": ["@babel/preset-env", "@babel/preset-react"]
我尝试了许多变体,但我不明白为什么这不适用于开发模式。
【讨论】:
以上是关于如何将依赖于 Styled Components 的 React 组件库提供给另一个也具有 Styled Comopnents 依赖项的库?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 styled-components 将样式应用于 React Native 中的自定义组件?
如何使用 styled-components 将 prop 传递给 Material-UI 组件
如何将 Nextjs + styled-components 与 material-ui 集成
如何使用 input[type="submit"] 属性将 CSS 转换为 Styled-Components?
Styled-components vs Emotion - 如何在 Styled-components 上重新应用 css`style` 函数