Babel plug-in
This article mainly has the following contents
- Why implement a plug-in
- The knowledge required to implement plug-ins
- How to do that
- It may be needed in the business
Why implement a plug-in
Want to know more
The knowledge required to implement plug-ins
- A little bit of
AST
knowledge- AST basic explanation and parameters
- AST online compilation tool
- A little bit of compilation principles and how Babel builds
- Compilation principle
- Babel and AST documents
- A little English reading ability @babel/types. The development process needs to use the type of Babel, need to understand its type and use method
How to do that
Here we simply implement a Babel with an optional chain of operations
- Create an empty folder
- npm install –save-dev @babel/core @babel/cli
- .gitignore .babelrc.json
- .gitignore node_modules
- .babelrc.json
{ "plugins": [ "./plugins/optional-chaining-plugin" // We develop plug-in locations]}Copy the code
- src/index.js
// What to compile function demo(foo) { returnfoo? .bar; }Copy the code
- Plugins /optional-chaining- plugins/optional-chaining-plugin
Writing transformation rules
- Learn what Babel does
- Babel is designed to convert older VERSIONS of JS or non-JS or JSON files into JS for browsers to recognize and run
- Babel’s conversion process
-
The conversion process
- Resolution (parse)
- Receive the code and convert to an AST structure
- Two steps
- Lexical analysis
- The lexical phase transforms the string form code toTokens 流
You can think of tokens as a flat array of syntax fragments:n * n Copy the code
[{type: {... },value: "n".start: 0.end: 1.loc: {... }}, {type: {... },value: "*".start: 2.end: 3.loc: {... }}, {type: {... },value: "n".start: 4.end: 5.loc: {... }},... ]Copy the code
each
type
There is a set of attributes to describe the token:{ type: { label: 'name'.keyword: undefined.beforeExpr: false.startsExpr: true.rightAssociative: false.isLoop: false.isAssign: false.prefix: false.postfix: false.binop: null.updateContext: null},... }Copy the code
Like AST nodes, they also have them
start
.end
.loc
Properties. .
- Syntax analysis
- The parsing phase converts a token flow into the AST form. This phase uses the information in the tokens to transform them into an AST representation structure that makes subsequent operations easier.
- Two steps
- Translation (transform)
- Add, update, and remove the generated AST structure
- Generate (generator)
- Converts the transformed AST into string code, and creates a source map.
- What kind of online Babel conversion is compatible with the content to be compiled into the browser
- The original writing
function demo(foo) {
returnfoo? .bar; }Copy the code
- Browser compatibility
function demo(foo){
return foo == null ? void 0 : foo.bar
}
Copy the code
- View the AST structure of old and new code
- Visit astexplorer.net/
- Start coding the Babel Plugin component template
module.exports = function (babel) { const { types: t, template } = babel return { name: 'my-plugin'.visitor: { // expression expression}}}Copy the code
- Since we’re dealing with optional operators here, let’s look it upDocument @ Babel/types, the alternative operation is
optionalMemberExpression
.
module.exports = function (babel) {
const {
types: t,
template
} = babel
return {
name: 'my-plugin'.visitor: {
// expression expression
optionalMemberExpression(path) {
const {object, property} = path.node
// Path is the node currently traversed. This node is the one that hits the optional operator, foo? Bar, we need to replace this node
path.replaceWith(
// Foo == null? Void 0: foo.bar
// Each expression must be created. Babel's built-in types already encapsulates all expressions for us to call directly
// First is the ternary operator XXX? xxx : XXX, went to the document for the ternary operator expression https://www.babeljs.cn/docs/babel-types#conditionalexpression tc onditionalExpression (test, consequent, alternate)
// three entries, test keys alternate. If you don't know what it is, it's okay. Put this code foo == null? Void 0: foo.bar is translated into ast. You'll see what you want under asttree on the right, including Test Consequent Alternate.
t.ConditionalExpression( // Construct the ternary operator
// Construct the ternary operator to say hello to the left
t.BinaryExpression( // https://www.babeljs.cn/docs/babel-types#binaryexpression
'= =',
t.identifier(object.name), // https://www.babeljs.cn/docs/babel-types#identifier
t.nullLiteral(), // https://www.babeljs.cn/docs/babel-types#nullliteral
),
// The ternary operator left of the colon
t.UnaryExpression( // https://www.babeljs.cn/docs/babel-types#unaryexpression
"void",
t.numericLiteral(0) // https://www.babeljs.cn/docs/babel-types#numericliteral
),
// The ternary operator to the right of the colon
t.MemberExpression( // // https://www.babeljs.cn/docs/babel-types#memberexpression
t.identifier(object.name),
t.identifier(property.name),
)
)
)
}
}
}
}
Copy the code
T. sequence Expression Ast effect
Optimization, actually we can usebabel
thetemplate
So let’s optimize the way we write it@babel/template
t.UnaryExpression(
"void",
t.numericLiteral(0)),/ / change for
template.expression('void 0') (the),Copy the code
- Do it, and then do it
yarn start
"start": "babel src/ -d dist/"
. The compiled code appears in Dist
Scenarios used in the business
We haven’t found….. yet I look forward to your supplement
Advanced knowledge of required plug-ins
- Visitor pattern
- A deeper understanding of compilation principles
- Data structures and algorithms
This article refer to
- Beginner’s Guide to Babel plug-in development
- Babel for ES6? And Beyond!
- Manual of the Babel plug-in
- Walk you through the AST abstract syntax tree
- Why know AST
- Babylon-A Primer – Code Update & Remove