1. What is Postcss

PostCSS is the parser that parses CSS into a tree of objects (AST). The plugin then changes the tree, and finally PostCSS generates a new CSS string from a modified object tree.

PostCSS is not a preprocessor, nor is it a way to add syntactic sugar, it is a framework for creating CSS tools that transform styles using JavaScript plug-ins. A PostCSS plug-in is a function that receives and usually converts the CSS AST from the PostCSS parser. PostCSS allows anyone with JavaScript experience to create their own plug-ins.

2. postcss7

2.1 Writing plug-ins

Write plugin syntax for postCss7.x:

// PostCSS needs to be imported
const postcss = require('postcss');

module.exports = postcss.plugin('postcss-merge2'.(opts = {}) = > {
    return (root, result) = > {
        root.walkRules(rule= >{... })}})Copy the code

3. New features brought by Postcss8

Plug-in developers now have the option of using a new API in postcss8.0 that can speed up builds and reduce dependencies for end users of their tools.

3.1 Writing plug-ins

Use the new plugin API, without importing PostCSS, to get all the classes and methods as the second argument to the function:

- const { decl: Declaration } = require('postcss')

  module.exports = {
    postcssPlugin: 'postcss-example', -once (root) {+ Once (root, {Declaration}) {... }}module.exports.postcss = true
Copy the code

Complete example:

// No need to import postCSS
module.exports = (opts = {}) = > {
  return {
    postcssPlugin: 'PLUGIN NAME'.Rule(rule, { Declaration }) {
      
    },
    Declaration (decl) {
      
    }
  }
}

module.exports.postcss = true
Copy the code

3.2 Smaller node modules

Previously, each plug-in had PostCSS in its dependencies. This can cause problems with having multiple copies of PostCSS in node_modules:

Node_modules/autoprefixer/ node_modules/ postcss/ ← Repeat stylelint/ node_modules/ postcss/ ← repeat postCSs-normalize / Node_modules/postcss/ ← RepeatCopy the code

Postcss8.0 will ensure that there is only one PostCSS instance in node_modules. You can control the end user’s node_ module size by editing package.json to move Postcss8 to peerDependencies: All plug-ins will now use the same version of PostCSS as their dependencies.

{
    "dependencies": {-"postcss": "^ 7.0.10"
    },
    "devDependencies": {+"postcss": "^ 8.0.0." "
    },
  + "peerDependencies": {+"postcss": "^ 8.0.0." "+}}Copy the code

3.3 Faster CSS building

Every PostCSS plug-in has been traversed through this tree. Usually a plug-in just looks for a few attributes, but it still needs to scan the entire tree. If there are a lot of plug-ins in the build tool (or if you use a preset plugin that has a lot of plug-ins in it, such as postCSS-Env or stylelint), most of the processing time will be spent in the plugin, running the tree over and over again.

// The walkDecls method traverses the tree to find all declared nodes
root.walkDecls(decl= > {
  if (decl.prop === 'will-change') {
    decl.cloneBefore({ prop: 'backface-visibility'.value: 'hidden'})}})Copy the code

Postss8.0 provides a visitor API for plug-ins, where all plug-ins can share a single scan of the CSS tree. It improves CSS processing speed by 20%. To use a single scan, remove the root.walk* call and move the code to the Declaration(), Rule(), AtRule(), or Comment() methods in the plug-in object.

  module.exports = {
    postcssPlugin: 'postcss-dark-theme-class',
-   Once (root) {
-     root.walkAtRules(atRule= >{-// Slow
-     })
-   }
+   AtRule (atRule) {
+     // Faster+}}module.exports.postcss = true
Copy the code

4. Be aware of issues caused by version differences

4.1 Problem Description

Now you need to write a postCSS plugin that combines the margin, padding, and other properties written separately under a selector in the CSS, and integrate the plugin into an existing project. Such as:

div {
  margin-top: 10px;
  margin-bottom: 10px;
  margin-left: 10px;
  margin-right: 10px;

  /* After the merge */ 
  margin: 10px;
}
Copy the code

I first created a new project, installed PostCSS (there is no version specified when installing, it will install the latest version by default, the latest version of PostCSS is 8.3.6), looked up the information and wrote the plugin… Once written, it works fine.

But when you put the plug-in into an existing project, it doesn’t work, and the conversion doesn’t work. Very strange.

It turned out that the postCSS used in the project was version 7.x, so I tried to upgrade to version 8, and the plugin worked fine.

4.2 the reason

The postcss7.x plugin syntax is different from the postcss8.x plugin syntax.

If you’re new to writing postCSS plug-ins, go aheadPostcss websiteorGitHub repository for PostcssCheck information,By default, it will lead us to write a plug-in for Postcss8.x using the new plug-in syntax. However, if the postCSS version in your project is 7.x, plug-ins written using the new syntax may have problems with the following error indicating that you need to use postCSS version 8There are two solutions

  1. Write the plugin using the new plugin syntax, and upgrade the postCSS version in the project to 8. Refer to the PostCSS 8.0 plugin migration guide
  2. In this project, the postCSS version is still 7.x, so you need to use the old plug-in syntax to write the plug-in, refer to the postCSS 7.x version of the plug-in

Summary: Plug-ins created for Postcss7.x work for Postcss8.x, but plug-ins created for Postcss8.x may not work for Postcss7.x.

Data of 5.

  • Postss8.0 features
  • PostCSS8.0 plug-in migration Guide
  • Github.com/postcss/pos…
  • Postcss development history
  • Postcss7. X document
  • Postcss8. X document
  • Postcss API​

Front-end learning exchange QQ group: 862748629 point I joined