明天是暗恋她的第90天,但我马上就要失恋了
因为组织架构变动,我要换到一个离她很远的中央
暗恋她的90天里,我始终在997
每天都在跟同类互相残杀
我厌倦了和一群老男人加班的日子
她是这段光明工夫里,惟一的光
她曾是年会的女主持
万千男人暗恋的女神,而我只是个加班狗
她身边都是鲜花和掌声
我身边全是抠脚大汉和LSP
她每天衣着难看的衣服和名牌包包
而我只有一件粑黄色上衣,和一个装电脑的大黑包
我配不上她,但又被她深深的吸引
结婚7年来,我每天上班就回家
不抽烟不喝酒不近女色
腾讯男德第一人
当初竟然对她产生了情愫
本认为我很专一,遇见她当前才明确
原来男人真的能够同时爱上好几个女人
离别之前,不晓得要不要跟她表白
如果表白,她肯定会说我是个坏蛋
如果本人长的再难看点,是不是就不必自大了
惋惜没有如果,我是个完满的垃圾
就这样心烦意乱的上线了一版代码,配置文件还批改错了
间接崩出线上大bug
所有网页全副 404 not found
1000封报警邮件狂轰滥炸
boss婉转的发来1星绩效的暗示
都要哭了
配置文件这种货色,人工去批改,太容易受情绪影响而改错了
这些反复且易出错的操作,应该用工程化、自动化伎俩去解决
babel批改js配置文件实现原理
残缺代码参考:github。
像那些js配置文件,外面可能有很多的非配置代码,而且一次可能要批改好几个文件
比方咱们在前端我的项目,要插入一个页面,须要批改router、menus等配置文件,还要手动拷贝页面模板等等
这些高反复机械化操作,人工批改非常容易出错
咱们能够间接用babel来操作AST形象语法树,通过工程化去精准批改。让babel去帮咱们找到指定地位,并正确插入配置代码。咱们在做工程化开发的时候,常常会用到babel去操作AST。
首先咱们理解一下什么是AST
AST,形象语法树(Abstract Syntax Tree)它是源代码语法结构的一种形象示意。它以树状的模式体现编程语言的语法结构。
咱们应用babel来转化和操作AST,次要分为三个步骤:解析(parser)、转换(traverse)、生成(generator)
操作AST三大阶段
如下图,如果咱们想通过babel,在配置文件外面插入一段配置代码,应该怎么实现呢
解析(parser)
第一步:读取配置文件代码,并生成AST形象语法树
let configJsData = fs.readFileSync(configJsPath, "utf8");
而后将配置文件代码生成AST形象语法树
const parser = require("@babel/parser");let configJsTree = parser.parse(`${configJsData}`,{ sourceType: "module", plugins: [ "jsx", "flow", ], });
configJsTree就是咱们的AST了
加上sourceType: "module"
这个配置属性,是为了让babel反对解析export和import
转换(traverse)
转换(traverse)阶段,就是要遍历整个AST形象语法树,找到指定的地位,而后插入对应的配置代码。
代码如下:
const traverse = require("@babel/traverse").default;traverse(configJsTree, { ObjectProperty(path) { // 插入配置文件代码 }, });
咱们应用@babel/traverse
的traverse办法进行遍历整个AST
其中ObjectProperty
的作用是在遍历AST过程中,辨认出所有的Object对象,因为咱们是要将配置代码插入一个Object对象,所以应用的是ObjectProperty
。如果要将配置插入数组中,就应用ArrayExpression
。
而后咱们开始进行配置代码的插入,将代码
{ key: "testPath", icon: HomeOutlined, exact: true,}
插入如下的地位
咱们须要在traverse
的ObjectProperty
进行地位的查找和代码插入
首先咱们要找到key: 'home'
的地位
代码如下:
traverse(configJsTree, { ObjectProperty(path) { if ( path.node.key.name === "key" && path.node.value.value === "home" ) { // 这就是 key: 'home'的地位 } }, });
通过path.node.key.name
和path.node.value.value
找到对象属性为key
并且对象值为home
的Object对象
找到地位后开始插入代码
traverse(configJsTree, { ObjectProperty(path) { // 搜寻并辨认出配置文件里key: "home" 这个object对象地位 if ( path.node.key.name === "key" && path.node.value.value === "home" ) { path.parent.properties.forEach(e=>{ if ( e.key.name === "children" ) { // 找到children属性 } }) } }, });
通过path.parent.properties
找到对象的父级,而后遍历父级下的所有属性,找到children
这个属性。这就是咱们要插入的地位。
接下来咱们要结构要插入的数据
{ key: "testPath", icon: HomeOutlined, exact: true,}
结构数据的代码如下:
const t = require("@babel/types");const newObj = t.objectExpression([ t.objectProperty( t.identifier("key"), t.stringLiteral("testPath") ), t.objectProperty( t.identifier("icon"), t.identifier("HomeOutlined") ), t.objectProperty( t.identifier("exact"), t.booleanLiteral(true) ), ]);
能够看到用dentifier
来标识对象的属性,用stringLiteral
标识字符串数据,booleanLiteral
标识boolean值,这些类型都能够在@babel/types
查问到。
最初一步,将结构好的数据插入:
e.value.elements.push(newObj)
实现~!
将所有 traverse 阶段代码汇总起来如下:
const traverse = require("@babel/traverse").default;const t = require("@babel/types");traverse(configJsTree, { ObjectProperty(path) { // 搜寻并辨认出配置文件里key: "home" 这个object对象地位 if ( path.node.key.name === "key" && path.node.value.value === "home" ) { path.parent.properties.forEach(e=>{ if ( e.key.name === "children" ) { const newObj = t.objectExpression([ t.objectProperty( t.identifier("key"), t.stringLiteral("testPath") ), t.objectProperty( t.identifier("icon"), t.identifier("HomeOutlined") ), t.objectProperty( t.identifier("exact"), t.booleanLiteral(true) ), ]); e.value.elements.push(newObj) } }) } }, });
生成(generator)
这个阶段就是把AST形象语法树反解,生成咱们惯例的代码
const generate = require("@babel/generator").default;const result = generate(configJsTree, { jsescOption: { minimal: true } }, "").code;fs.writeFileSync(resultPath, result);
通过@babel/generator
将AST形象代码语法树反解回原代码,jsescOption: { minimal: true }
配置是为了解决中文为unicode乱码的问题。
至此咱们就实现了对js配置文件插入代码,最终后果如下:
以上就是通过babel操作AST,而后精准插入配置代码的全流程,残缺代码参考:github。
结尾
线上所有都稳固后
回头看了下女神
她正在照镜子涂口红
就静静坐着,都好喜爱好喜爱
她很爱笑、每周三都会去打篮球,早上10:30准时到公司、喜爱咖啡和奶茶
她的生存每天都是一首歌
而我只会敲代码,加班加到腿抽筋
据线人说,她曾经有男朋友了,又高又帅又有钱
而我又老又丑、不仅穷还秃
据说她还很年老,而我曾经32
还有不到3年就35岁,我的工夫不多了
怎么能眷恋世间烟火呢
女人只会影响我敲代码的速度
哎。。。真该死
我还是默默地守护她、反对她、观赏她吧
不打扰是屌丝最高级的告白
只是惋惜的是
至始至终,我都不晓得她叫什么
咱们从没说过一句话
都是我一个人的独角戏
鲁迅说过:“我晓得妳不是我的花,但能途经妳的盛放,我不胜荣幸”
。。。。。。
深夜空无一人的总部大楼
就这样默默坐在彼此的身边
就当咱们也已经在一起过吧
这次离别,可能就再也见不到了
不晓得妳会不会想起我
也不晓得我会不会爱上别的女孩
然而还是谢谢妳
惊艳了我每个加班的夜晚
goodbye my lover
————— yours 小蝌蚪
作者:第一名的小蝌蚪,公众号:第一名的小蝌蚪