preface

For Styled Components, I have recently contacted a project and think it is a good CSS-in-JS scheme. Of course, many people also refer to the emotion scheme. As I have not had in-depth contact with the latter, I will not say who is good and who is bad.

This article briefly records the following questions:

  1. Styled Components overrides problems modifying the STYLE of Antd
  2. Co-existing with the Css, how can THE Css overwrite the Style of the Styled Components
  3. Styled Components use Css Modules
  4. Styled Components use Less
  5. The Css Modules configuration fails

Environment to prepare

First we initialize a project using the create-react-app scaffolding, which is pretty handy for people who develop React.

npx create-react-app styled-demo
Copy the code

After initialization, the following dependencies are installed. Here, the antD Styled components and the customized create-React-app project are installed. The ANTD configuration can be viewed.

yarn add styled-components babel-plugin-import react-app-rewired customize-cra antd
Copy the code

Create config-overrides. Js in the root directory, add customized-cra to configure babel-plugin-import to dynamically import Antd components

const { override, fixBabelImports } = require('customize-cra');

module.exports = override(fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',}));Copy the code

Replace NPM scripts in package.json, where the original eject does not need to be replaced. React-app-rewired does not provide this functionality

"start": "react-app-rewired start"."build": "react-app-rewired build"."test": "react-app-rewired test".Copy the code

Streamline App. Js

import React from 'react';
import { Button } from 'antd';
import './App.css';

function App() {
  return (
    <div className="App">
      <Button type="primary">Button 1</Button>
    </div>
  );
}

export default App;
Copy the code

After yarn Start runs, you can see a blue Antd button

Styled Components overrides problems modifying the STYLE of Antd

Create a button by creating a new SRC /style.js file

import styled from 'styled-components';
import { Button } from 'antd';

export const StyledButton = styled(Button)`
  &.ant-btn-primary {
    color: red;
  }
`;
Copy the code

Add to app.js, and run it again to see two buttons

<StyledButton type="primary">Button2</StyledButton>
Copy the code

Taking a quick look at the structure here, all styles in the head tag will be appended to the style tag, and those generated by our Styled – Components will be loaded to the tail, according to the Css precedence, so it is not difficult to understand how we override Antd styles above.

As styled- Components are placed last, what will give the highest precedence in Css if used in conjunction with the usual style of introducing Css? Which brings us to the next part

Co-existing with the Css, how can THE Css overwrite the Style of the Styled Components

Add styles to SRC/app.css

.CssDiv {
  color: #ccc;
}
Copy the code

SRC/App. Add js div

<StyledDiv className="CssButton">Div</StyledDiv>
Copy the code

#ccc

So how do we do that? Either adjust the order of references (not easy with WebPack, and our WebPack configuration is still invisible), or adjust the priority of Css weights; Here’s a trick: just repeat the class selector in SRC/app.js. This is a way to increase the Css priority and change the div text to # CCC

.CssDiv.CssDiv  {
  color: #ccc;
}
Copy the code

Styled Components use Css Modules

React-rewired provides a quick way to enable CSS modules with names like xxx.module. CSS /less

.ModuleText {
  color: # 000;
}
Copy the code

SRC/app.js to add, both magnolia can see the effect

<div className={style.ModuleText}>
    css modules
</div>
Copy the code

Configuration is less

Install dependencies related to less

yarn add less less-loader
Copy the code

Change the demo.module. CSS to demo.module.less; Change the reference in SRC/app. js to config-overriddes.js and run yarn start again

module.exports = override(fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
  addLessLoader({
    localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.}));Copy the code

eggs

After you try less, some of you see the following mistakes

Css - Loader ^ 3.0.0
break Change

Yarn add customize-cra@next // Update the latest customize-craCopy the code
// Update configuration addLessLoader({cssModules: {localIdentName: "[local]--[hash:base64:5]" // if you use CSS Modules, and custom `localIdentName`, default is '[local]--[hash:base64:5]'.}})Copy the code

Run it again and it will be ok. If you want to know more specific reasons, you can refer to the issue. What ideas can you write here? At present, the modification of this function has not been officially completed. The picture below is my revision idea. If you agree with it, please give a thumbs-up and I will propose PR later. Maybe the author will adopt it

Attached is a screenshot of the customize-cra next branch source code from January 17, 2020. Is that why we added the cssModules property