已发布的样式组件反应库无权访问用户应用程序 ThemeProvider
Posted
技术标签:
【中文标题】已发布的样式组件反应库无权访问用户应用程序 ThemeProvider【英文标题】:Published styled-components react library does not have access to user app ThemeProvider 【发布时间】:2021-05-07 20:01:49 【问题描述】:所以我正在为这家公司构建一个设计系统,并且组件系统在设计系统故事书中正确显示。但是当我在消费者应用程序中导入它时,我收到以下错误
TypeError: Cannot read property 'width' of undefined in theme.border.width
设计系统项目:
/// src/components/Button/index.js
import Wrapper from './styles'
import React from 'react'
export const Button = (props) => (
<Wrapper ...props>
children
</Wrapper>
)
.
///src/components/Button/styles.js
export const Wrapper = styled.button`
...
border-width: $(theme) => theme.border.width;
...
`
.
/// .storybook/preview.js
import React from 'react'
import ThemeProvider from 'styled-components'
import GlobalStyle from '../src/styles/globalStyles'
import theme from '../src/styles/theme'
export const parameters =
actions: argTypesRegex: '^on[A-Z].*'
export const decorators = [
Story => (
<ThemeProvider theme=theme>
<GlobalStyle />
<Story />
</ThemeProvider>
)
]
.
/// src/index.js
...
export Button from 'components/Button'
export theme from 'style/theme'
...
.
/// babel.config.js
module.exports =
presets: [
[
'@babel/env',
modules: false
],
['@babel/preset-react']
],
plugins: [
[
'styled-components',
s-s-r: true,
displayName: true,
preprocess: false,
minify: false
]
]
.
///rollup.config.js
import babel from 'rollup-plugin-babel'
import includePaths from 'rollup-plugin-includepaths'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
export default [
input: 'src/index.js',
output: [
name: 'rollup-tutorial',
file: 'dist/index.js',
format: 'es'
],
plugins: [
babel(
exclude: 'node_modules/**'
),
includePaths(
paths: ['src'],
extensions: ['.js', '.json', '.html']
),
peerDepsExternal()
]
]
.
/// package.json
"name": "design-system",
"main": "dist/index.js"
"files: ["dist"],
"scripts":
...
"build": "rollup --config"
...
,
"devDependencies":
"@babel/core": "^7.12.10",
"@babel/preset-react": "^7.12.10",
"@babel/preset-env": "^7.12.13",
"react": "17.0.1",
"react-dom": "17.0.1",
"rollup": "^2.38.4",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-includepaths": "^0.2.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
"styled-components": "^5.2.1",
,
"peerDependencies":
"prop-types": ">= 15.x.x",
"react": ">= 17.x.x",
"styled-components": ">= 5.x.x",
App 消费者 NextJs 默认配置
/// .babelrc
"presets": ["next/babel"],
"env":
"development":
"plugins": [
[
"styled-components",
"s-s-r": true,
"displayName": true
]
]
,
"production":
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
"s-s-r": true,
"displayName": false
]
]
.
///package.json
...
"dependencies":
...
"design-system": "../design-system/",
...
...
.
/// pages/_app.js
import ThemeProvider from 'styled-components'
import theme from 'design-system'
function MyApp( Component, pageProps )
console.log(theme)
return (
<ThemeProvider theme=theme>
<Component ...pageProps />
</ThemeProvider>
)
.
///pages/index.js
import Button 'design-system'
export default function Home()
return (
<Button />
)
注意:
console.log(theme)
打印预期的主题,但按钮无法访问样式组件提供的主题。
我想我在 babel rollup 或其他东西中遗漏了一些重要的配置
注2:
我已经尝试将组件包装在 withComponent HOC 中 唯一可行的解决方案是下一段代码
///pages/index.js
import Button 'design-system'
import useTheme 'styled-components'
export default function Home()
const theme = useTheme()
return (
<Button theme=theme />
)
但这失去了使用上下文的全部意义
提前致谢
【问题讨论】:
【参考方案1】:在使用故事书和情感/样式组件开发组件库时,我遇到了类似的问题。问题是我正在使用来自消费者应用程序的样式化组件的 ThemeProvider,就像您在 _app.js
中所做的那样。解决方案是使用库的 styled-component 包在组件库上创建和导出自定义 ThemeProvider,如下所示:
import ThemeProvider from 'styled-components'
import theme as defaultTheme from '../src/styles/theme'
const CustomThemeProvider = ( theme = defaultTheme, children ) => (
<ThemeProvider theme=theme>
children
</ThemeProvider>
)
export CustomThemeProvider
然后在您的消费者应用中使用
/// pages/_app.js
import CustomThemeProvider, theme from 'design-system'
function MyApp( Component, pageProps )
console.log(theme)
return (
<CustomThemeProvider theme=theme>
<Component ...pageProps />
</CustomThemeProvider>
)
【讨论】:
【参考方案2】:样式组件常见问题解答建议不要将样式组件与捆绑包一起提供。这为我解决了上述问题。
https://styled-components.com/docs/faqs#i-am-a-library-author-should-i-bundle-styledcomponents-with-my-library
【讨论】:
以上是关于已发布的样式组件反应库无权访问用户应用程序 ThemeProvider的主要内容,如果未能解决你的问题,请参考以下文章
将 Blazor 组件渲染到现有 div(Blazor 无权访问)
svn访问版本库时一直提示:please wait while the repository browser is initializing,没有其他反应