来源

前言

最近有个项目接触到了Styled-Components觉得这是一个不错的Css-In-Js的方案,当然也有很多人提到emotion这个方案,因为我没有深入的去接触过后者,这里就不说谁好谁坏的。
这篇文章简单记录一下以下问题:

  1. Styled Components覆盖修改Antd的样式的问题
  2. 和Css共存,如何让Css覆盖Styled Components的样式
  3. Styled Components使用Css Modules
  4. Styled Components使用Less
  5. Css Modules配置报错问题

    环境准备

    首先我们使用Create-React-App脚手架初始化一个项目,对于开发React的人来说这个脚手架那是相当的好用。
    1. npx create-react-app styled-demo
    2. 复制代码
    初始化完成后执行安装以下依赖,这里主要是安装antd styled-components和定制化Create-React-App项目的两个包, 配置Antd方面的内容可以查看
    1. yarn add styled-components babel-plugin-import react-app-rewired customize-cra antd
    2. 复制代码
    根目录创建config-overrides.js,用customized-cra来增加babel-plugin-import配置动态引入Antd组件
    1. const { override, fixBabelImports } = require('customize-cra');
    2. module.exports = override(fixBabelImports('import', {
    3. libraryName: 'antd',
    4. libraryDirectory: 'es',
    5. style: 'css',
    6. })
    7. );
    8. 复制代码
    替换package.json中的npm scripts,这里原本的eject无需替换,react-app-rewired并不提供该功能
    1. "start": "react-app-rewired start",
    2. "build": "react-app-rewired build",
    3. "test": "react-app-rewired test",
    4. 复制代码
    精简App.js
    1. import React from 'react';
    2. import { Button } from 'antd';
    3. import './App.css';
    4. function App() {
    5. return (
    6. <div className="App">
    7. <Button type="primary">Button 1</Button>
    8. </div>
    9. );
    10. }
    11. export default App;
    12. 复制代码
    之后yarn start运行就可以看到一个Antd的蓝色按钮了

    Styled Components覆盖修改Antd的样式的问题

    新建src/style.js来创建一个button
    1. import styled from 'styled-components';
    2. import { Button } from 'antd';
    3. export const StyledButton = styled(Button)`
    4. &.ant-btn-primary {
    5. color: red;
    6. }
    7. `;
    8. 复制代码
    App.js中增加,后再运行就可以看到两个按钮了
    1. <StyledButton type="primary">Button2</StyledButton>
    2. 复制代码
    Styled Components常见样式使用技巧 - 图1
    简单看一下这里的结构,head标签中所有的样式都会被style标签追加进去,而我们styled-components生成的会被加载到尾部,根据Css优先级那么就不难理解我们上述覆盖Antd样式的原理了。
    那么有人问了既然styled-components被放在了最后,那如果和普通引入Css的方式一起使用怎么样才能让Css中的优先级最高呢?这就引出我们的下一部分
    Styled Components常见样式使用技巧 - 图2

    和Css共存,如何让Css覆盖Styled Components的样式

    src/App.css中添加样式
    1. .CssDiv {
    2. color: #ccc;
    3. }
    4. 复制代码
    src/App.js添加div
    1. <StyledDiv className="CssButton">Div</StyledDiv>
    2. 复制代码
    Styled Components常见样式使用技巧 - 图3可以看到我们的按钮3是红色,并没有变为#ccc的颜色这是为什么呢?我们来看一下style标签的顺序,依旧是styled-components生成的排在了最后。Styled Components常见样式使用技巧 - 图4
    那我们应该如何做呢?要么调整引用顺序(用webpack不太好调整,而且我们webpack配置目前还是不可见的),要么调整Css权重的优先级;我们采取第二种方案这里有个小技巧,直接将src/App.js中的class选择器重复一遍,这里通过这种方式来提升Css优先级就让div的文字变为#ccc实现效果了
    1. .CssDiv.CssDiv {
    2. color: #ccc;
    3. }
    4. 复制代码

    Styled Components使用Css Modules

    新建demo.module.css,这里需要注意react-rewired给我们提供了一种快速开启css modules的方式,只需要命名为xxx.module.css/less 等都可以直接开启
    1. .ModuleText {
    2. color: #000;
    3. }
    4. 复制代码
    src/App.js中添加,既可以玉兰看到效果
    1. <div className={style.ModuleText}>
    2. css modules
    3. </div>
    4. 复制代码
    Styled Components常见样式使用技巧 - 图5

    配置less

    安装less相关依赖
    1. yarn add less less-loader
    2. 复制代码
    修改上面的demo.module.css为demo.module.less;同时src/App.js中的引用也要修改哦 修改config-overriddes.js 保存之后重新运行yarn start即可
    1. module.exports = override(fixBabelImports('import', {
    2. libraryName: 'antd',
    3. libraryDirectory: 'es',
    4. style: 'css',
    5. }),
    6. addLessLoader({
    7. localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
    8. })
    9. );
    10. 复制代码

    彩蛋

    各位尝试less之后有些人是不是看到了下面的错误
    Styled Components常见样式使用技巧 - 图6这是因为新的Create-React-App中引入的Css-Loader^3.0.0有一些break Change; 类似于localIdentName这样的属性在css-loader中移动到了modules对象中了,custom-cra在调用addLessLoader方法的时候无法正确传递配置;那么怎么解决呢?
    1. yarn add customize-cra@next //更新最新的customize-cra
    2. 复制代码
    1. // 更新配置
    2. addLessLoader({
    3. cssModules: {
    4. localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.
    5. }
    6. })
    7. 复制代码
    重新运行之后就ok了。 想知道更多具体的原因可以参见issue,这里大家有什么想法可以写上去目前该功能还没有正式完成修改。下图是我的修改想法如果赞同点个赞,后续我也会提出pr的说不定作者就采纳了哈哈
    Styled Components常见样式使用技巧 - 图7
    附上2020年01月17日customize-cra next分支源码截图,这就是我们为什么要添加cssModules属性的原因
    Styled Components常见样式使用技巧 - 图8