Cause
- After the child applies the style, it is loaded. Because the parent and child apply the style with the same name, the style is overwritten
thinking
Take the parent application elementUi2.0 as an example and the child application elementPlus as an example
- Check the official document. The official document gives two solutions, which are implemented one by one. It is found that none of them has been solved
start(opts?) Options { sandbox - boolean | { strictStyleIsolation?: boolean, experimentalStyleIsolation?: boolean } - Optional. Whether to enable the sandbox. The default value is true. } When configured as { strictStyleIsolation: true } Indicates that strict style isolation mode is on. In this mode qiankun The container of each micro application is wrapped with a shadow dom Node to ensure that the style of the micro application does not affect the global. When experimentalStyleIsolation Set to true When, qiankun The style added by the sub application will be overwritten, and a special selector rule will be added for all style rules to limit their influence scope.
-
Scheme 1: using shadow dom is not a brainless scheme, so it has to be adapted. reason: All subapplication selectors fail,Other issues.
-
Scheme 2: the experimental scheme does not solve the component style attached to the body after use, which will cause various problems.
-
Parent app replaces all class prefixes
- I tried to replace all class prefixes with webpack plug-ins, but I didn't know enough about webpack plug-ins to solve the problem
-
Prefix the subapplication style selector (similar to the official scheme 2)
- Using postcss plugin to solve
- Problems encountered: some styles cannot be solved by this method, such as component styles mounted under the body
What is postcss
- Is a tool that allows the use of JS plug-ins to convert styles, a parser, and a tool for compiling css.
- PostCSS receives a CSS file and provides an API to analyze and modify its rules (by transforming CSS rules into an abstract syntax tree).
The difference between and less sass
less sass is a preprocessor that supports extended css syntax.
Postcss is neither a pre processor nor a post processor. It has a wide range of functions, and the important point is that postcss can be combined with less/sass
What can we do with it
- Solve the problem of global CSS
- Use advanced CSS features in advance
- Better CSS readability
- Prompts (Linters)
- more
Application of postcss
- autoprefixer
- stylelint
- ... and more than 200 plug-ins
Abstract syntax tree (may consist of the following parts)
- Root: the root node of AST, which represents each css file
- AtRule: the Rule of each selector starting with @
- Rule: css selectors and declarations form a CSS rule. For example, input, button {font size: 20px;} the curly braces are declarations
- Declaration: declaration, key value pair like color: black;
- Comment: comment, which can exist in the selector, @ selector's parameters and css style key value pairs. The comments in the node will be saved in the raws attribute of the node
AST example
Root { raws: { semicolon: false, after: '' }, type: 'root', nodes: [ Rule { raws: [Object], type: 'rule', nodes: [Array], parent: [Circular *1], source: [Object], selector: '.tab-dialog' }, ], source: { input: Input { css: '.tab-dialog {\n' + ' position: absolute;\n' + ' top: 0;\n' + ' bottom: 0;\n' + ' right: 40px;\n' + ' width: 500px;\n' + ' background: white;\n' + ' box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);\n' + ' display: flex;\n' + ' flex-direction: column;\n' + '}\n' + '.tab-dialog-header {\n' + ' display: flex;\n' + ' justify-content: space-between;\n' + ' font-size: 20px;\n' + ' padding: 10px;\n' + '}\n' + '.tab-dialog-header .el-icon-close {\n' + ' cursor: pointer;\n' + '}\n' + '.tab-dialog-main {\n' + ' flex: 1;\n' + ' overflow: auto;\n' + ' padding: 0 10px;\n' + ' box-sizing: border-box;\n' + '}\n' + '.tab-dialog-footer {\n' + ' text-align: right;\n' + ' padding: 10px;\n' + '}', hasBOM: false, file: '/Users/mac/Desktop/workspace/fe-dgp-web/v3/src/views/data/taskEdit/TabDialog.vue' }, start: { line: 1, column: 1 } } }
General process
- Parsing CSS into an abstract syntax tree (AST tree)
- Pass the AST tree to any number of plug-ins for processing
- Convert the processed AST tree back to a string
Source string → Tokenizer → Parser → AST → Processor → Stringifier
Development of postcss plug-in
const postcss = require('postcss') module.exports = postcss.plugin('postcss-add-css-prefix', function (opts = {}) { const { prefix = '' } = opts // Receive two parameters, the first is the ast of each css file, and the second parameter can obtain the information related to the conversion result (including the information related to the current css file) function plugin(css, result) { if (!prefix) return // If no prefix is passed in, the following logic will not be executed css.walkRules((rule) => { // Traverse all the current ast rule nodes const { selector } = rule // A flag is added to prevent the node from repeatedly executing the logic after updating and entering the dead loop if ( selector.includes('.el-') && !selector.includes(prefix) && !rule.flag && !selector.includes('.el-popper') ) { rule.flag = true const clone = rule.clone() // console.log(selector) clone.selector = `${prefix} ${selector}` rule.replaceWith(clone) } else if ( !selector.includes(prefix) && !rule.flag && selector.includes('.el-popper') ) { // Handle the styles of nodes mounted under the body } }) } return plugin })