Author: Zhang Jun

preface

Speaking of the web front end, we always remember the three components of the front end: HTML, JS and Css. But CSS is a bitter memory in the eyes of most Web development engineers.In the early days of a large project, as shown in this image, the complexity of Css can be overwhelming.

These problems are caused by Css itself, for example, Css syntax is not strong enough, there is no nested hierarchy, and a lot of repetitive selectors need to be written. Another example is that without a mechanism for variables and proper style reuse, logically related attribute values must be repeated in literal form, making it difficult to maintain.

To solve these problems, Css preprocessors were born.

Css preprocessor

What is a CSS preprocessor?

The preprocessor is based on the Css and has its own Domain specific language (DSL) on it to solve the problems encountered by the Css.

Css gives Web engineers new capabilities in Css. This article takes Sass as an example. First: fully compatible with Css3. Rapid development in the front, also will have to keep up with, that is the update speed, the browser browser manufacturers too much, different effects on different vendors on the interpretation of the Css standards, many new features on the new features can’t be used directly in the browser, the Css in different browser compatibility is a lot of problems. But you can safely use the new features of Css3 in Sass.

Second, it expands the functionality of Css by adding variables, nesting, mixing and other functions. One of the things that Css has long been criticized for is its lack of logic. Adding logic makes code more reusable. Fixed the problem that the syntax of the original Css was not powerful enough. The easiest things to get started with are nesting and variables.

// sass 
$red_color: #ea7142;
$green_color:#299e22;
#hello_sass{
    color: $red_color;
    .font_green_color{
        color: $green_color;
    }
}
===>
#hello_sass{
    color: #ea7142;
}
#hello_sass .font_green_color{
    color: #299e22;
}
Copy the code

Css preprocessor code does not run directly in the browser, so we need to compile and parse it into Css files. In this process, we can add a lot of build steps, such as code review, compression, sorting, and so on.

Hence the birth of the Css post-processor, which is the focus of this article – Postcss

Postcss introduction

Postcss is a tool that uses JS plug-ins to transform styles. Postcss plug-ins check your CSS.

One of the most commonly used plug-ins is autoprefixer, which adds vendor browser prefixes, eliminating the need to constantly write “webkit” code for compatibility. Then you might wonder why the VUE project I create doesn’t need prefixes. The plugins autoprefixer are configured by default in vue-CLI when the project is created. There are many amazing add-ons in Postcss, such as PostCSS-px-to-viewPort, which automatically converts px to accommodate different screen widths, and the Gospel of OBSessive-compulsive, Postcss-sorting, which automatically sorts Css properties according to specified rules, etc.

Of course, on paper, you have to find a way to do that, so let’s try out Postcss.

Postcss practice

Build a JS project.

mkdir test-poctcss npm init npm install --save-dev css-loader style-loader webpack webpack-cli mini-css-extract-plugin NPM install --save-dev postcss postCSs-loaderCopy the code

Initialize the project, use WebPack to package the project, and create a directory structure

We use postcss.config.js to configure postCSS. For now, let’s just take Autoprefixer as an example.

npm install --save-dev autoprefixer

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
Copy the code

Thus, we have successfully inserted the plug-in into the Postcss method. The next step is to introduce Postcss to Webpack. When installing Postcss, we also introduced the poctcss-loader package. When we package csS-related content, we call postCSs-loader first.

// webpack.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { entry: './src/js/index.js', output: { filename:'bundle.js', path:path.resolve(__dirname,'dist') }, module: { rules:[ { test: /\.css$/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'postcss-loader' ] }, ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'main.css' }) ] } // index.js import '.. /style/index.css' const div = document.createElement('div') div.innerHTML = 'hello postcss' div.className = 'hello_postcss' document.body.append(div) // index.css .hello_postcss{ color: #00DD00; display: flex; }Copy the code

The WebPack, JS and CSS files are configured. We use Webpack for packaging

webpack --mode development
Copy the code

Ok. It was packed successfully. Let’s take a look at what the CSS file under DIST looks like.

// main.css
.hello_postcss{
    color: #00DD00;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
}
Copy the code

You can see that Postcss transforms the display: flex package in our CSS into multiple properties with different prefixes.

Postcss principle

Why is POCTCSS able to do this? Through reading the analysis of the source code, that. When we build the project, the webpack will send the CSS file contents to postCSs-loader, and postCSs-Loader will parse the plugin in postcss.config, and send it to PostCSS, and postCSS will parse the incoming CSS. Convert it to an AST, then operate on the AST through various plug-ins, finally serialize the new CSS, and finally return the result to postCSS-Loader for the operation of the next webpack loader.Now that you’ve seen how PostCss works, let’s look at how Autoprefixer works. Take the display property.

class DisplayFlex extends Value {
  constructor (name, prefixes) {
    super(name, prefixes)
    if (name === 'display-flex') {
      this.name = 'flex'}}... prefixed (prefix) {letspec, value ; [spec, prefix] = flexSpec(prefix)// spec is the year version prefix is the browser prefix
    if (spec === 2009) {
      if (this.name === 'flex') {
        value = 'box'
      } else {
        value = 'inline-box'}}else if (spec === 2012) {
      if (this.name === 'flex') {
        value = 'flexbox'
      } else {
        value = 'inline-flexbox'}}else if (spec === 'final') {
      value = this.name
    }

    return prefix + value
  }
	...
}
Copy the code

Autoprefixer gets the browser versions that we have configured in Postcss to support. The content of our CSS file has been converted to AST by Postcss, and the corresponding attribute name and value can be obtained. In Autoprefixer, there are hooks for many attributes. When there are hooks in the AST that contain attributes in the hooks, they are handled by the hooks, which perform the transformations shown above, such as adding browser prefixes to the attributes. (Only a lot of special judgment can be made to be compatible with the different browsers supported by different vendors, so you can see how much historical burden CSS has).

conclusion

This article has just taken a peek at Postcss, and there are many different ways to use it.

First, Postcss is not a replacement for CSS preprocessors, although it is. Second, Postcss is a plug-in tool, and a rich plug-in ecosystem means it can cover the vast majority of scenarios and businesses. Finally, Postcss optimizes the entire Web development process, removing historical baggage and enhancing the robustness of CSS.

Github address: github.com/godj1001/te…