0%

how to add a babel plugin in cra app

起因

趁乱摸鱼写会儿 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'));