JavaScript Babel-Loader 自定义入门
前言
突然觉得 babel-loader https://github.com/babel/babel-loader 很好玩,比较贴近AST,然而编译原理一直是噩梦,没学懂,好在这东西不需要什么编译原理的知识。但还是涉及到语法解析等操作,所以拿过来学一学还是挺好的。
什么是 Babel
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 代码转换为当前和旧版浏览器或环境中的向后兼容版本的 JavaScript。 以下是 Babel 可以为您做的主要事情:
转换语法
目标环境中缺少Polyfill功能(通过@ babel / polyfill)源代码转换(codemods)
更多
1 2 3 4 5 6 7 // Babel Input: ES2015 arrow function [1, 2, 3].map((n) => n + 1); // Babel Output: ES5 equivalent [1, 2, 3].map(function(n) { return n + 1; });
代码转化就涉及到了语法解析,这便是我们的重点
自定义
首先新建一个项目 webpack 项目 babel-demo
目录结构如下
1 2 3 4 5 6 7 8 9 10 11 . ├── README.md ├── babel-plugin-transform-class │ └── index.js ├── dist │ └── bundle.js ├── package-lock.json ├── package.json ├── src │ └── index.js └── webpack.config.js
新建 package.json 并使用 npm install 安装所需插件
1 npm install -D babel-loader @babel/core @babel/preset-env webpack
package.json
1 2 3 4 5 6 7 8 9 10 11 12 { "scripts": { "start": "webpack" }, "dependencies": {}, "devDependencies": { "@babel/core": "^7.5.5", "@babel/preset-env": "^7.5.5", "babel-loader": "^8.0.6", "webpack": "^4.39.1" } }
新建 webpack 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var path = require('path'); module.exports = { entry: './src/index.js', mode: 'development', output: { path: path.join(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /\.js$/, loader: 'babel-loader', options: { plugins: [ "transform-class" ] } } ] } }
module 里面的 rule 便是配置我们自定义的 babel 插件,transform-class 是插件名。
手写插件
下面是一个简单的插件
babel-plugin-transform-class/index.js
1 2 3 4 5 6 7 8 9 10 11 // A plugin is just a function module.exports = function ({ types: t }) { return { visitor: { Identifier(path) { let name = path.node.name; // reverse the name: JavaScript -> tpircSavaJ path.node.name = name.split('').reverse().join(''); } } }; }
将 babel-plugin-transform-class 文件夹移动到 node-modules 目录下即可。当运行 webpack 的时候,便会运行这个插件,这个插件会把 node 的 name 做反转。
我们的 demo
1 2 3 4 function babel() { let javascript = 'hello babel'; console.log(javascript); }
打包后
1 eval("function lebab() {\n let tpircsavaj = 'hello babel';\n elosnoc.gol(tpircsavaj);\n}\n\n//# sourceURL=webpack:///./src/index.js?");
我们看到变量名都反转了。
我们还可以实现更多·····更多属性,方法在这里 https://babeljs.io/docs/en/next/babel-types.html
参考
AST https://astexplorer.net/