This is my first blog post. I participated in the creation activity of gold diggers and started my writing path together.

background

  • The current project is developed based on React + ANTD. The existing skin changing scheme is too costly for a large project

The target

  • Low access cost in the project
  • Low technical implementation complexity
  • Meet the needs of dynamic skin change

Matters needing attention

The following points need to be noted when using this solution

  • This function is dynamically modifiedCSS VariableImplementation, so in IE pages will not be displayed properly.
  • The function in[email protected]Version up support.
  • This feature requires that all styles be imported at once (792KB), resulting in a performance loss. (The optimization method, described below, reduces the file size to50kb, performance improvement10Times)

How to use

Introducing antd. Variable. The CSS

Replace the current project with the CSS Variable version of the introduced style file:

-- import 'antd/dist/antd.min.css';
++ import 'antd/dist/antd.variable.min.css';
Copy the code

Note: If you use babel-plugin-import, you need to remove it.

Static method configuration

Call the ConfigProvider configuration method to set the theme color:

import { ConfigProvider } from 'antd';

ConfigProvider.config({
  theme: {
    primaryColor: '#25b864',}});Copy the code

Optimize large CSS files

The antD.variable. CSS file needs to be introduced globally, which causes the following problems:

  • The file773kb, there will be a certain amount of network consumption (this can not be tolerated)
  • Will overwrite the original style, resulting in part of the page style disorder (the project is too large, the scope of influence is not controllable, this is unbearable)

The solution

From the antD.variable. CSS file, use re to extract cSS3 variable-related styles. This can reduce the size of the file without overwriting the style.

The code is as follows :(github address)

const fs = require("fs");

// Extract the CSS selector
const cssSelectorReg = /\}[^\}]+\{/g;
// Extract CSS values
const cssValueRreg = /\{[^\{}]+\}/g;

const data = fs.readFileSync("./antd.variable.css"."utf-8");
const cssSelectorMatch = data.match(cssSelectorReg);
const cssValueMatch = data.match(cssValueRreg);
const htmlCss = 'html ' + cssValueMatch[0];
const otherCss = fs.readFileSync("./other.css"."utf-8");

let result = [];
cssSelectorMatch.forEach((item, index) = > {
    const cssSeletor = item.replace('} '.' ');
    const cssValue = cssValueMatch[index + 1].replace('{'.' ');
    let cssRule = cssSeletor + cssValue;

    // Filter out those containing var
    if (cssValue.includes('var(')) {
        if (cssSeletor.includes(The '@')) {
            cssRule += '\n}';
        }
        result.push(cssRule)
    }
})

// Save the content after the var attribute
const cssString = result.join(' ');
const cssLineArr = cssString.split('\n');
// Filter out CSS properties with var variables and add the important property
const cssVarLineArr = cssLineArr.filter(line= > line.includes('var(') | |! line.includes('; '))
const cssVarLineStr = htmlCss + cssVarLineArr.join('\n') + otherCss;
fs.writeFile('./antd.variable.revision.css', cssVarLineStr,'utf8'.function(err){
    if(err)
        console.log('Error writing file, error:'+err);
    else
        console.log('ok');
})
Copy the code
Contents of the CSS file before slimming

Slimmed down CSS file contents (only CSS variable related content)

OK, perfect!

Other

Share a pit record below

Dynamic routing is used in the project, and CSS is loaded on demand. In this case, the CSS style loaded later overwrites the previous style, causing the CSS variable property to be overwritten (dynamic peels do not take effect).

At this point, there are two solutions:

1. Listen for route changes, and then dynamically load the file again through JS

When extracting cSS3 variable related styles, add them at the end of each line. Important attribute. This implementation is easy, you just need to put the const cssVarLineArr = cssLineArr. Filter (line = > line. Includes var (‘ (‘) | |! line.includes(‘; ‘)) this line of code into a const cssVarLineArr = cssLineArr. Filter (line = > line. Includes var (‘ (‘) | |! line.includes(‘; ‘)).map(line => line.replace(‘); ‘, ‘)! important; ‘))

conclusion

Author: HashTang

Personal Space: HXKJ.VIP

Reprint please indicate the source: juejin.cn/post/703743…

Welcome questions and exchanges!