用|用 Node 搭建最小实现脚手架
前言
本文介绍使用 Node 做一个脚手架,便于快速开发项目。我们开发的是脚手架,而非项目,目前本人只有一个脚手架—— Koa 脚手架 ,后续写到 React、webpack 时,会搭建属于自己的一套 H5 端的开发模板。本文以实现最小脚手架为出发点展开写作,后续也会再次基础上添砖加瓦
引子
A:大 B 哥,Node 能做什么?
B:搭建 Web 服务噜
A:不仅如此,它还能操作系统
B:怎么说?
A:知道 Webpack 吗?它就是用 Node 写的。还有像 create-react-app、 vue-cli、@tarojs/cli 这些,都是用 Node 写的,这些 cli 被称为脚手架,你只要使用一些命令就能下载模板快速开发
B:(各种羡慕、吹捧后),我也想做一套自己的脚手架
A:我教你啊
一个脚手架的思路
看create-react-app、 vue-cli、@tarojs/cli 的各自的仓库,我们能得出一些共同点,例如多套模板、友好的交互、优美的 UI 等等。我们这里以 taro 为例,先用用,看看,再仿着做一个
文章图片
它是怎么做到选择不同的模板,能生成不同的文件呢?明明只有一个基础模板啊,选择 scss 就生成 scss 文件,选择 TypeScript 生成 TS 文件,现在还看不懂源码,以后写完 webpack 再来看看,我们这里只先做一个最简单的脚手架
创建工程
mkdir azhu-cli
cd azhu-cli
npm init -y
【用|用 Node 搭建最小实现脚手架】然后在 package.json 中写点项目信息
需要安装的 npm 包 我们先列个表格,查看一下各个 npm 包是什么,有什么用,后续在写代码时一步步添加进去
包名称 | 说明 |
---|---|
commander | 执行复杂的命令 |
inquirer | 问答交互 |
download-git-repo | 下载远程模板 |
chalk | 让你 console.log 出来的字带颜色,比如成功时的绿色字 |
ora | loading |
index.js
,在代码中写入#!/usr/bin/env node
console.log('hello world')
在终端中运行 node 程序,输入 node 命令
node index.js
可以正确输出
hello world
,代码顶部的 #!/usr/bin/env node
是告诉终端,这个文件要使用 node 去执行一般 cli 都有一个特定的命令,例如
taro
,git
等,我们设置我们的命令—— azhu
。如何让终端识别这个命令呢?很简单,在 package.json 文件中添加一个字段 bin
,并且声明一个命令关键字和对应执行的文件:# package.json
...
"bin": {
"azhu": "index.js"
}
...
然后我们测试一番,在终端中输入
azhu
,会提示:![用|用 Node 搭建最小实现脚手架](https://img.it610.com/image/info9/81940e88ef31421a9f35f818a56fb6b2.jpg)
文章图片
为什么会这样呢?通常我们在使用 cli 工具时,都需要先安装它,比如 vue-cli,@tarojs/cli,使用前需要全局安装:
npm i vue-cli -g
npm i @tarojs/cli -g
而我们的 azhu-cli 并没有发布到 npm 上,当然也没有安装过,所以终端现在还不认识这个命令。通常我们想本地测试一个 npm 包,可以使用
npm link
这个命令,本地安装这个包,我们执行一下:npm link
再执行
azhu
命令,就看到 hello world
了注:npm unlink 卸载本地包执行复杂的命令 commander:处理命令行交互
- 自带了 -V,-h 交互
- 可以通过
program.command
添加交互 program.parse
将命令参数传入 commander 管道中,一般放在最后执行
npm i commander --save
改造
index.js
#!/usr/bin/env nodeconst program = require('commander')
const package = require('./package.json')
program.version(package.version)
program.parse(process.argv)
运行
azhu -h
![用|用 Node 搭建最小实现脚手架](https://img.it610.com/image/info9/b80d3d82d56b470995f6cf5f83bae23e.png)
文章图片
添加问答操作 inquirer 添加问答操作
npm i inquirer --save
语法很简单,直接看代码:
inquirer
.prompt([
{ type: 'input', message: '请输入项目名称', name: 'name' },
{
type: 'list',
message: '请选择项目模板',
name: 'template',
choices: ['koa-basic'],
},
])
.then((answers) => {
console.log('answers', answers)
})
每个选项中的 name 为答案输出的值
![用|用 Node 搭建最小实现脚手架](https://img.it610.com/image/info9/ae341db1e4f647e2a589dfb5bb97df9c.jpg)
文章图片
克隆模板 download-git-repo
- 下载远程模板
npm i download-git-repo --save
原本使用 shelljs,但是死活下载不下来,只能选择另一个工具
当我们下载写好项目名字,选择好模板后,下一步就要从远程仓库上把模板下载过来
.then((answers) => {
console.log('正在拷贝项目,请稍等')
const remote = 'https://github.com:johanazhu/koa-basic#master'
const tarName = answers.name
download(remote, tarName, { clone: true }, function (err) {
if (err) {
console.log(err)
} else {
console.log('成功')
}
})
})
添加 UI 交互 有时候下载远程仓库时会花很多时间,我们必须为了体验,需要加一些 UI 效果优化体验
chalk & ora
npm i chalk ora --save
chalk 是给 console 加颜色
ora 是加 loading 效果的
...
.then((answers) => {
console.log('正在拷贝项目,请稍等')
const remote = 'https://github.com:johanazhu/koa-basic#master'
const tarName = answers.name
+ const spinner = ora('download template......').start()
download(remote, tarName, { clone: true }, function (err) {
if (err) {
+ console.log(chalk.red(err))
spinner.fail()
} else {
+ console.log(chalk.green('成功'))
spinner.succeed()
}
})
})
效果如下:
![用|用 Node 搭建最小实现脚手架](https://img.it610.com/image/info9/615241e0d6474566aa68237f268a1906.jpg)
文章图片
发布 npm 先登录 npm,再发布
npm login...npm publish
额外知识点 包管理方式
![用|用 Node 搭建最小实现脚手架](https://img.it610.com/image/info9/f2960d86a2c34f58aa677f3287a879d5.jpg)
文章图片
monorepo
- 将多个项目代码存储在一个仓库力的软件开发策略
- 把所有的项目相关都放在一个仓库(比如 React,Babel,Umi,Taro)
- 集中管理
- 优势
- 统一工作流
- 降低基建成本
- 提高团队协作效率
- 劣势
- 体积问题
- 权限问题
- 版本控制
- 按模块放在为多个仓库(webpack、rollup)
- 优势
- 灵活
- 安全
- 劣势
- 代码复用
- 版本管理
- 开发调试
- 搭建基础架构
我个人更喜欢 multirepo 的哲学
有人上升到哲学层面,其实俺觉得不同的项目应采用合适自己的管理方式,像 webpack、rollup 之类,项目独立想比较强,就可以用使用 multirepo ,而像 React,Umi,Taro 之类的框架,它首先要拆分功能点,其次每个子库之间需要与主库有所依赖,如果采用 multirepo 方式,关联起来会很麻烦,采用统一管理的方式能节省很多时间
常见问题 一:使用
shelljs
常有报错,暂时解决不了,所以用 download-git-repo
这种方式fatal: unable to access 'https://github.com/johanazhu/koa-basic/': OpenSSL SSL_read: Connection was reset, errno 10054
解决方案
打开 Git 命令页面,执行 git 命令脚本:修改设置,解除 ssl 验证
git config --global http.sslVerify "false"
注:git config --list 查看你的 config 信息二:
download-git-repo
报错误'git clone' failed with status 128
解决方案:https://github.com/wuqiong7/Note/issues/17
我将 remote 地址改成:https://github.com:johanazhu/koa-basic#master 就好了
Github 已发布:https://github.com/johanazhu/azhu-cli
参考资料
- 搭建一个企业级脚手架
- 从零开发一个 node 命令行工具
推荐阅读
- 安信可ESP32C3系列|安信可经验分享 | WiFi保持连接状态下低功耗的实现,适用于ESP32/ESP32C3/ESP32S3系列模组二次开发
- Java|Java 超基础讲解String的使用
- 在Typescript中如何使用for...in详解
- 使用FreeRTOS遇到死等异常的解决
- 聊聊JavaScript中.?、??、??=的用法以及含义
- 最佳实践 | 微搭低代码使用 Excel 创建应用
- 人工智能在云计算中能发挥怎样的作用()
- 厉害!我带的实习生仅用四步就整合好SpringSecurity+JWT实现登录认证!
- 一场由TiCDC异常引发的GC不干活导致的Tikv硬盘使用问题
- 技能类相关|【工具使用】SecureCRT的下载、安装图文详细过程介绍