介绍Vladimir[1]发现自己一直很讨厌用bash写的自动化流程脚本,偶然发现同事也有类似的想法,于是分享了他认为用JavaScript写自动化脚本的优势,看看如果他能说服大家一起建立一个更好的生态。相关地,Google的zx[2]项目由此诞生,并在去年的JavaScript工具趋势调查中名列第一。今年最受欢迎的项目是Google的zx,它支持使用JavaScript或TypeScript编写简单的命令行脚本。zx支持在代码中嵌入任意bash表达式(ls、cat、git等),并借助JavaScript模板字面量获取结果。zx涵盖了几个包提供的功能:node-fetch:使用与浏览器中相同的API发出HTTP请求;fs-extra:运行文件系统;Globby:匹配给定用户友好模式的文件名;其次是他分享的一些观点:我在日常工作中也体会到大家似乎有一个共识,就是在写自动化构建脚本的时候应该默认使用bash。希望这篇文章能给你带来一些不一样的思考,或许JavaScript写起来会不会更好?我们先看看几个可能的优势:你的团队可能最熟悉JSdev和CI机器很可能默认安装了Node并且可以直接访问其他JS工具Node是一个跨平台运行时进程间通信是异步的,并且它非常方便如果您时间不够,这里有一个快速比较表:这是您团队的主要语言大多数前端团队对JS的熟悉程度超过bash。Node有一个特殊的API,但通常它具有熟悉的功能,如一流的函数、循环和承诺。庆典?我已经弄乱了几年,我不确定它是如何工作的——语法很熟悉,但在意想不到的地方有所不同,大多数变量是字符串,是否存在模块?如果我错了,请不要纠正我,我不在乎了。我在使用它时一直在谷歌上搜索……每个体面的程序员都需要学习bash吗?有病!如果你的后端同事需要对你的项目做一些紧急的改动,他应该学点JS。C风格的语法让任何人都能大致了解代码的意图。当然bash从这一点看也差不多,但是JS至少不比这里差。使用JS实现脚本自动化是JS优先团队中最合乎逻辑的选择。运行时很可能已经安装。即使你的bash脚本成功运行,麻烦也没有结束,因为它通常会在另一台机器上失败(比如你,AlpineDocker容器......)。各种shell[3](SH、ASH、BASH、ZSH)都略有不同,并且在不同的Linux发行版中并不完全通用。你当然可以手动挑选需要的包,或者手动重写逻辑,但这真的很浪费时间。使用Node,缺少运行时的问题非常罕见——CI机器无论如何都可以运行npm/yarn,它们与node捆绑在一起。此外,一旦编写了节点程序,它通常会在每台计算机上运行。开箱即用的跨平台特性这引出了下一点——节点是一个跨平台运行时,可以在linux、mac和windows上运行良好。是的,MacOS是POSIX兼容的,但许多命令在选项和输出格式上仍然存在细微差别。现在,您需要Windows支持吗?尽管大多数前端开发人员使用Mac,并且存在用于Win的bash端口。但是开箱即用的免费支持总是好的:它降低了为开源项目做贡献的障碍。当我需要匆忙在Windows服务器上启动开发服务器时,通常会很不愉快。经理想玩你的项目,但他使用的是Win电脑。Node团队花费了大量时间来抽象化操作系统之间的差异。忽略这一点并坚持使用bash会适得其反。直接访问其他JS工具前端工作流(webpack/parcel/babel/PostSS)中的大多数工具都公开节点API。甚至像esbuild和swc这样的非JS工具也提供节点绑定。如果您的自动化编排在节点上运行,访问这些API很简单:只需导入包并调用函数。在bash中,有两个与基于节点的工具集成的麻烦选项:通过一种奇怪的选项格式调用CLI。编写一个最小的JS包装器来调用节点API,从bash调用它。作为一个额外的好处,由于许多工具的CLI在单独的包中(如@babel/CLI),如果你直接使用节点API,你可以跳过安装,节省一点npmi时间。良好的进程间通信节点作为自动化运行时的一个很酷的方面是它的IPC功能。有时您更喜欢通过CLI而不是节点API使用其他工具。此外-在节点中,这可以通过child_process[4]异步和跨平台完成!您甚至可以像shell的管道运算符|那样在不同进程之间传输输出。虽然内置的Stream和child_processAPI可能不太符合人体工程学,但您可以根据自己的喜好使用包装器——我更喜欢execa。bash还擅长进程管理,但对我来说有太多的可能性——看这个stackoverflow问题:它提到了五种不同的并行运行命令的方式[5],如果你不知道自己在做什么,那就是你很容易搬起石头砸自己的脚。庞大的npm生态系统为各种各样的问题提供了很好的解决方案。我最喜欢的是用于管理子进程的execa[6]、用于处理CLI选项的yargs[7]和用于输出样式的chalk[8]。是的,存在许多类似的命令行工具,但必须使用特定于操作系统的包管理器(apt?brew?apk?)安装它们。人们真的不想处理这种问题。此外,您安装的任何CLI包也可以通过spawn/exec在节点中使用。因此,以下是我选择JS/node来管理复杂的自动化工作流程的主要原因:JS是您团队的主要语言!节点运行时通常安装在本地和CI中,因为您正在处理npm/Spread。node运行跨平台,不像bash和make。node可以直接访问其他JS工具。节点IPC(用于编排CLI工具)非常适合,尤其是在使用execa时。在node.js中有许多用于编写CLI工具的有用包。当然避免使用node是有原因的(比如缺少自动化用例的教程,不熟悉node的异步复杂性),但我仍然相信它是JS项目中构建自动化流程的最可靠选择。弗拉基米尔:https://thoughtspile.github.io/2022/02/14/js-automation参考资料[1]弗拉基米尔:https://twitter.com/thoughtspile[2]zx:https://github.com/google/zx[3]各种shell:https://en.wikipedia.org/wiki/Shell_script[4]child_process:https://nodejs.org/api/child_process.html[5]提到了五种不同的运行命令方式并行:https://stackoverflow.com/questions/3004811/how-do-you-run-multiple-programs-in-parallel-from-a-bash-script[6]execa:https://github.com/sindresorhus/execa[7]yargs:https://github.com/yargs/yargs[8]chalk:https://github.com/chalk/chalk
