使用 golang 重写 nodejs cli

本文最后更新于:2022年11月17日 凌晨

场景

由于吾辈使用 monorepo 管理所有项目,lib 模块初始化的构建时间已经不能接受,所以最近两天吾辈在尝试使用 golang 重写 lib/cli 构建工具 @liuli-util/cli,验证 golang 到底可以做到多快。

@liuli-util/cli 是吾辈创建一个针对于库和 CLI 应用程序打包的零配置构建工具,但也支持一些额外的常用功能,包括生成模板项目、同步配置、部署等。

1643537400132

实现

saki npm,所有测试均在 liuli-tools 完成,它是一个有 44 个模块组成的 monorepo,其中有 28 个需要构建。

整体基于 esbuild 来重写 liuli-cli 的 build 命令,支持 build lib/cli 以及自定义目标。下面是一些吾辈在重写之后做的测试,证明使用 golang 可以大幅度提高 lib 构建性能,它是如此快速以至于有可能将它放在 postinstall 中。

命令均使用 time seq 10 | xargs -i <cmd> 重复执行 10 次

saki build

基于 esbuild 构建 lib 或 cli 程序,它非常快。

1
2
saki build lib # 构建 lib
saki build cli # 构建 cli

性能测试

下面两个 cli 都基于 esbuild 实现的构建,但后者真实运行时间很长,因为 nodejs 本身加载代码也需要时间(而且很慢)。

下载二进制文件安装

1
2
3
4
5
6
7
8
9
10
11
12
13
$ saki build lib

real 0m0.647s
user 0m0.060s
sys 0m0.183s
# 平均 64.7ms/次

$ saki build cli

real 0m2.831s
user 0m0.106s
sys 0m0.275s
# 平均 283.1ms/次

npm 全局安装

1
2
3
4
5
6
7
8
9
10
11
12
13
$ saki build lib

real 0m2.724s
user 0m0.482s
sys 0m1.665s
# 平均 272.4ms/次

$ saki build cli

real 0m4.622s
user 0m0.587s
sys 0m1.438s
# 平均 462.2ms/次

liuli-cli

1
2
3
4
5
6
7
8
9
10
11
12
13
$ liuli-cli build lib

real 0m6.882s
user 0m0.648s
sys 0m1.364s
# 平均 688.2ms/次

$ liuli-cli build cli

real 0m8.687s
user 0m0.587s
sys 0m1.333s
# 平均 868.7ms/次

saki run

一个 pnpm --filter . run 的替代命令,尝试提高多线程运行命令的效率。

1
2
3
4
5
saki run setup # 在所有模块运行 setup 命令(如果有这个命令)
saki run --filter libs/* setup # 在所有匹配 libs/* 的模块中运行 setup 命令
# 使用 --filter 数组
saki run --filter libs/* --filter apps/* setup # 或者使用 , 分割
saki run --filter libs/*,apps/* setup

性能测试

pnpm + liuli-cli + dts

1
2
3
4
5
6
$ pnpm --filter . run setup

real 4m49.648s
user 0m0.593s
sys 0m1.391s
# 平均 1034.4ms/个

pnpm + liuli-cli

1
2
3
4
5
6
$ pnpm --filter . run setup

real 1m3.847s
user 0m0.468s
sys 0m1.484s
# 平均 228ms/个

saki + liuli-cli

1
2
3
4
5
6
$ saki run setup

real 1m19.657s
user 0m0.497s
sys 0m1.494s
# 平均 284.4ms/个

pnpm + saki(几乎是使用 js 工具链难以想象的)

1
2
3
4
5
6
$ pnpm --filter . run setup

real 0m16.168s
user 0m0.435s
sys 0m1.590s
# 平均 57.7ms/个

npm saki

1
2
3
4
5
6
$ saki run setup

real 0m17.545s
user 0m0.651s
sys 0m1.618s
# 平均 62.6ms/个

下载二进制文件安装 saki

1
2
3
4
5
6
$ saki run setup

real 0m13.742s
user 0m0.046s
sys 0m0.258s
# 平均 49.0ms/个

Windows 下使用 git bash –filter 参数请用 "" 包裹

结论

目前来看,builder 提高的比较明显,而 run 则几乎和 node 相差无几(有时候甚至更慢了)。

吾辈可能会继续尝试使用 golang 重写更多的前端基础工具,nodejs 的性能目前而言看起来并不能用。


使用 golang 重写 nodejs cli
https://blog.rxliuli.com/p/43b8b01afb9c412f9af2c4abecc30874/
作者
rxliuli
发布于
2022年1月30日
许可协议