前端工程02 创建自己的脚手架工具
前一阵子用Egg做了一个Node服务端项目的重构,发现Egg相比于Koa和Express来说,感觉更适合于现阶段团队的Node开发,因为现在团队Node的代码根本没有任何规范和约定,乱的一坨,所以引入了Node,遵循它的规范,使用它预置的功能,对代码的可维护性提升还是比较大的。
开发完成后,在Egg的基础上增加了一点中间件,配置了一些插件和代码风格控制的配置,将这个模板抽离出来作为团队以后开发Node服务的基准模板,放在了Gitlab上。
原来的时候方法都是直接Clone这个项目,再去更改Git的相关信息等等,不是很方便。所以想试着做一个类似于简易的Vue-Cli这样的工具,能够直接拉取模板,并且直接生成对应的目录,配置一些简单的信息。
因为要实现的脚手架工具比较简单,没有那么多的配置,实现起来还是比较简单的。下面分几个部分记录自己学习的过程。
前言
前一阵子用Egg做了一个Node服务端项目的重构,发现Egg相比于Koa和Express来说,感觉更适合于现阶段团队的Node开发,因为现在团队Node的代码根本没有任何规范和约定,乱的一坨,所以引入了Node,遵循它的规范,使用它预置的功能,对代码的可维护性提升还是比较大的。
开发完成后,在Egg的基础上增加了一点中间件,配置了一些插件和代码风格控制的配置,将这个模板抽离出来作为团队以后开发Node服务的基准模板,放在了Gitlab上。
原来的时候方法都是直接Clone这个项目,再去更改Git的相关信息等等,不是很方便。所以想试着做一个类似于简易的Vue-Cli这样的工具,能够直接拉取模板,并且直接生成对应的目录,配置一些简单的信息。
因为要实现的脚手架工具比较简单,没有那么多的配置,实现起来还是比较简单的。下面分几个部分记录自己学习的过程。
控制台交互
使用Cli工具,必定要在控制台输入、输出一些相关的信息,可以使用Commander这个包,它可以接受并解析在控制台输入的参数process.argv
,它基本的使用方法如下:
1 | program.version('0.1.0') |
通过上面的配置,我们就可以通过program.init
拿到用户在控制台输入init a
时跟在init
后面的输入a
,我们将a
作为模板的目录名
然后在开始拉取模板之前,我们需要有一个Loading的提示,会更加友好,可以使用ora这个包,它用来在终端展示loading的图标。我们这里使用的也很简单,开始时展示图标和提示语:
1 | const spinner = ora('正在拉取Create-Egg-App模板...').start(); |
拉取成功或者失败后展示对应的图标和文字:
1 | // 成功 |
提示的文字我们还希望能带一些颜色,比如成功我们希望是绿色,失败时红色,这样会更加美观,我们就可以使用chalk这个包,它可以用来在终端中展示各种颜色:
1 | const chalk = require('chalk'); |
准备工作都就绪了,就差最关键的一步了,就是拉取模板了。
拉取模板
拉取模板我们也可以借助第三方的包来实现,要使用的就是download-git-repo这个包了,它可以帮助我们模板代码从各种仓库中拉取下来,它既可以通过SSH协议拉取Github的代码:
1 | github:owner/name |
也可以直接通过HTTPS拉取代码:
1 | direct:url |
它接受四个参数:
1 | dowanload(url, pathName, opts, callback) |
详细的配置还是参考它的文档吧。整个拉取代码的逻辑就基本完成了
1 | if (program.init && typeof program.init === "string") { |
优化
还有一点优化在changePackage
这个函数中完成了,这个函数会将模板中的package.json
的name
和version
,这个功能使用了原生的Node来实现
1 | const changePackage = () => { |
这段代码基本是Copy第一篇参考文章的,自己的Node并不灵,把这个段代码学习一下。
首先通过fs.readFile
来读取package.json
文件,查找文件路径时使用了process.cwd
,它表示当前执行Node命令时的文件夹路径名
Node中海油几个获取路径的方法,可以来看一下:
1 | __dirname: 获得当前执行文件所在目录的完整目录名 |
我们这里使用的是process.cwd()
,就是在执行当前的Node命令时的目录下,因为通过program.init
新建的目录是在执行Node命令的目录下
因为package.json
文件时JSON格式的,所以可以首先通过data.toString
将二进制文件转换为字符串,然后通过JSON.parse()
进行解析。
解析完成后修改相关字段,修改完成后再通过JSON.stringify
转换为字符串,它额外接受了两个参数,第二个参数用来在序列化过程中替换序列化的内容,第三个参数用来指定缩进空白字符串。
序列化完成后,再将内容通过writeFile
写会原来的package.json
文件。
使用
使用时为了避免全局安装,使用npx来拉取模板是很好的解决防范。具体使用时分为两种情况,一种是模板在内网的Gitlab上,一种是模板在公网的Github上。
先来看在Github上,模板的地址是https://github.com/duola8789/create-egg-app-zh
,我们先在NPM上注册账户,并通过npm login
登陆,然后将egg-cli-zh
发布到NPM上。
1 | NPM publish |
发布成功后,就可以直接使用npx拉取模板了:
1 | npx egg-cli-zh init [project_name] |
但是如果模板在内网的Gitlab上,egg-cli-zh
也不能发布到NPM上,那就使用ssh+git
来使用即可:
1 | npx git+ssh://git@gitlab/xxx/template.git init [project_name] |
至此,一个简易的脚手架工具就完成了。Egg-Cli-zh脚手架的源代码在这里,Create-Egg-App-zh的源码在这里。