起因
趁乱摸鱼写会儿 React ,用 CRA (create-react-app) 拉的项目模板。最近接触到了 CSS in JS
的写法,觉得很新奇很有趣。不用单独写一个样式文件来引入,而是可以用行内样式的方式或是 styled-components
的方式来编写样式。试着改写之前写过的 Comment List 模块的样式。碰到 1 个问题。
问题
我偏向于 styled-components
的写法,如下所示:
const Container = styled.div`
margin-top: 10px;
display: flex;
justify-content: space-between;
`;
如此,就可以把 Container 直接作为一个组件来使用,不会使得 JSX 的标签内容因为填塞了太多的样式而显得臃肿且影响阅读。
但我如何实现两个标签拥有相同的样式,但其中一个又要部分独有的样式呢?遂翻阅文档。
问题++
文档中提到了如何复用样式,每个创建出来的组件都会有 withComponents
这个方法,调用它就可以复制出一个相同样式的组件。但是这样似乎无法满足我的第二个要求,实现额外的定制化样式。
import styled from '@emotion/styled'
const Section = styled.section`
background: #333;
color: #fff;
`
// this component has the same styles as Section but it renders an aside
const Aside = Section.withComponent('aside')
render(
<div>
<Section>This is a section</Section>
<Aside>This is an aside</Aside>
</div>
)
这个问题也许可以在 styled-components
官网翻阅解决,因为 emotion
应该就是基于这个库的。但我没有再钻研这个,而是发现了另一个问题。关于样式嵌套。
嵌套一向是 CSS 预编译器的拿手好戏。在 styled-components
中的普通嵌套也完全没问题 。但是对于我们创建出的样式组件就难以在 native 环境下完成嵌套。需要额外安装一个 babel 插件来实现。那么问题来了,如何在 CRA 的定制模板中修改 babel 配置?
解决
其实这个问题有一个很简单的解法,就是 eject 出 CRA 的 webpack 配置,然后自行修改即可。但这样实在是太大费周章了。于是我查了查如何不影响项目结构而单独配置 babel 。
了解到了 react-app-rewired
customize-cra
可以实现 CRA 配置的修改。
修改启动命令的内容,配置 config-override.js
来添加新的 babel 配置。
const { override, addBabelPlugin } = require('customize-cra');
module.exports = override(addBabelPlugin('@emotion'));