linaria's initial experience and exploration of css architecture in react framework

Posted by ridiculous on Sat, 18 Dec 2021 01:03:09 +0100

Native css stage

I first came into contact with react a year ago. Before that, I had been using the vue framework. React has no restrictions on vue taking the style of the component as part of the template. At that time, only the original method can be used: one css file for each component is introduced into the component, and a pile of prefixes are added in front of each css selector to prevent style overwriting.
This can realize functions, but for componentization, there is no coupling between components and styles, and the problem of style coverage may still occur. Moreover, the prefixes in front are not very elegant and difficult to manage and maintain.

css Module phase

The second stage is css modularization. After completing the first react project independently, I reviewed the problems encountered and sought solutions. Later, I was lucky to read Ruan Yifeng's article about css module:
Link: CSS Modules usage tutorial
The following is an example of my usage in the project:
css file:

:global(.menu-wapper){
  color:green;
}
:local(.sub-menu){
    color:red;
}
:global(#root) :local(.name){}

js file:

import styles from "./index.css";
import React from 'react';
import ReactDOM from 'react-dom';
import classNames from "classnames";
const ComposeMenu = function(props){
    return <div>
      <div className={'menu-wapper'}>111</div>
      <div className={classNames(styles['sub-menu'],`submenu-${props.index}`)}>222</div>
    </div>
}
ReactDOM.render(
    <ComposeMenu index="1"/>,
    document.getElementById('root')
);

Generated after compilation:
css:

.menu-wapper{
  color:green;
}
.index_sub-menu_yWNJ9{
    color:red;
}
#root .index_name__Ol1S{}

The introduced styles is a class module, which can be passed through Access css rules. It is very convenient to use with some libraries such as classNames. The selector in the css file will add hash characters as the class name according to the path, file name, etc. to achieve the effect similar to the scope. Of course, if you don't want to be compiled, you need to add: global() keeps the original class name, and the two can also be mixed. Ruan Yifeng's blog is very detailed. I won't introduce it much. It's OK to use it with less and sass.

JSS solution

jss, as its name implies, is to generate css through js. It can directly improve the expression ability of css to the js level, and there are no problems with variables and complex calculations. In react, you can put components and styles in the same file to truly realize the coupling of style components. linaria is an excellent jss library, which comes from a Nuggets article I saw: Linaria may be the best JSS solution for React now.
The good thing is that when it runs at zero, even disabling js will not affect css loading. It has generated the corresponding css file and class name when packaging.
Let's see how to use it:

import {css} from 'linaria';
import { styled } from 'linaria/react';
import React from 'react';
import ReactDOM from 'react-dom';
const name = css`color:green;`;//Template based function
const Wrap = styled.div`color:red
&::after{
   content:"";
   width:10px;
   height:10px;
   display:block;
   background:#999;
}
`;
const ComposeMenu = function(props){
   return <div>
     <div className={name}>111</div>
     <Wrap>222</Wrap>
   </div>
}
ReactDOM.render(
   <ComposeMenu index="1"/>,
   document.getElementById('root')
);

You can directly generate class names or components through linaria. Here is the css generated by linaria:

.n166f1hf{color:green;}
.w18oyai6{color:red;}
.w18oyai6::after{content:"";width:10px;height:10px;display:block;background:#999;}

The effect is shown in the figure:

The configuration of webpack can be based on the github documentation. You may encounter an error: add @ babel / preset react( https://git.io/JfeDR ) to the ‘presets’ section of your Babel config to enable transformation . This prompts you to add a babel plug-in, but you have actually set the corresponding plugins. It should be the problem that linaria/loader conflicts with jsx syntax, which needs to be added additionally The babelrc file sets the global presets

Topics: React css