共计 4073 个字符,预计需要花费 11 分钟才能阅读完成。
明天是暗恋她的第 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 小蝌蚪
作者:第一名的小蝌蚪,公众号:第一名的小蝌蚪