手把手带你开发你的第一个前端脚手架
开发一个简单的脚手架
- 创建
npm
项目
首先创建一个文件夹,然后进入到该文件夹目录下,执行
npm init -y
- 创建脚手架入口文件
bin/index.js
,在index.js
中添加如下代码
#!/usr/bin/env node
console.log('hello cli')
- 配置
package.json
,添加bin
属性
{
"name": "yj-study-create-cli",
"version": "1.0.1",
"description": "",
"bin": {
"yj-study-create-cli": "bin/index.js"
},
"main": "index.js",
...
}
- 将脚手架发布到
npm
npm publish
当发布到npm
之后,通过全局安装来使用下我们上面创建的脚手架:
npm install -g yj-study-create-cli
此时我们会在/**/.nvm/versions/node/v16.14.0/bin
下看到该脚手架对应的可执行文件,这个文件就软链接到我们开发的bin/index.js
文件。
在命令行输入yj-study-create-cli
之后,就会打印出hello cli
。
这样我们就完成了一个简单脚手架的开发,是不是非常简单。
脚手架的调试
当我修改了脚手架内容之后,每次都要通过npm publish
上传到npm
上面,然后在npm install
才能看到效果,这样非常繁琐和不方便,那怎么调试脚手架呢?我们可以通过npm link
把本地脚手架文件通过软链接的形式链接到全局。
首先进入到脚手架目录,执行:
npm link
可以发现在node/bin
目录下面建立了一个可执行文件yj-study-create-cli
,它指向了lib/node_modules/bin/index.js
我们进入到这个bin/index.js
看下:
发现,它不是一个文件,它也是一个软链接,这个软链接指向了本地脚手架文件。
这样当我修改本地脚手架之后,在命令行输入yj-study-create-cli
就能看到修改的效果。这样就完成了本地脚手架的调试。
脚手架引入本地库文件
我们知道脚手架开发过程中肯定会引入其他的库文件,如果这个库文件不是npm
上的包,而是本地开发的,那如何引入呢?以及引入后如何调试呢?
首先我们新建一个本地库文件,执行npm init -y
,然后新建一个lib/index.js
,在里面写一个函数:
module.exports = {
sum(a, b) {
return a + b
}
}
然后修改package.json
的main.js
字段:
"main": "lib/index.js",
最后执行npm link
:
我们可以发现在node/v16.14.0/lib/node_modules/
下存在一个yj-study-create-lib
的软链接,它指向本地的库文件。
我们知道node/v16.14.0/lib/node_modules/
是全局安装npm包的位置,现在库文件也被安装在这里,说明这个库文件被全局安装了,那么就可以在任何工程中可以引用。
现在脚手架工程需要引入这个包,首先进入到脚手架工程目录中,然后执行npm link yj-study-create-lib
,它会在这个工程下安装yj-study-create-lib
这个包:
同时,需要手动的在package.json
中添加:
"dependencies": {
"yj-study-create-lib": "^1.0.0"
}
然后在脚手架中使用这个库文件:
#!/usr/bin/env node
const lib = require('yj-study-create-lib')
console.log(lib.sum(1, 2))
最后,在命令行中输入yj-study-create-cli
,就能获得正确的结果。
对npm link
的理解
库文件
如果你开发的某个库,当你执行npm link
时,就相当于在本地全局安装了这个库。
然后在使用这个库的工程中,执行npm link lib-name
,就会在工程下的node_modules安装这个库文件,这样就可以使用这个库了。
如果你在工程中不想引用这个库了,执行npm unlink lib-name
即可。如果出现报错,可以直接rm -rf node_modules
,然后再重新安装npm install
;
如果想解除库文件链接到全局的node_modules,执行npm unlink
,如果报错Must provide a package name to remove
,则执行npm unlink -g
即可。
脚手架文件
如果你开发的是一个脚手架,当你执行npm link
时,会在node/bin
下面创建一个可执行文件,这个可执行文件软链接到node/lib/node_modules
所对应的文件,同时这个文件又软链接到本地的脚手架工程文件,这样当你修改脚手架逻辑时,在本地就能看到修改后的效果。
如果脚手架开发完了,可以通过npm remove -g cli-name
去除对本地脚手架的软链接。
脚手架命令注册与参数解析
使用脚手架一般会跟上命令和相应的参数,比如:
yj-study-create-cli init --name
我们可以通过process.argv
拿到这些参数:
获取到这些参数之后,就可以执行对应的逻辑,比如:
const argv = process.argv
// 获取命令
const command = argv[2]
// 获取命令的参数
const options = argv.slice(3)
let [option, param] = options
option = option.replace('--', '')
// 命令对应的逻辑
const actions = {
init({ option, param }) {
console.log('执行init流程', option, param)
}
}
// 根据命令执行对应的逻辑
if (commands[command]) {
commands[command]({ option, param })
} else {
console.log('请输入正确的命令')
}
这样就完成了脚手架命令注册和参数解析。命令对应的逻辑,可以采用分包策略,单独用一个库lib来管理。
当然,一个出色脚手架不可能这么简单,下面我们来看看一个优秀的脚手架包括那些内容。
优秀的脚手架包括哪些内容?
1. 命令注册
以vue脚手架为例,它可以注册很多命令,每个命令所对应的逻辑都可以用一个单独的包来管理,这样就将复杂的系统拆分成若干个模块。
vue create
vue add
vue invoke
2. 参数解析
vue command [options] <params>
- options全称:
--version
、--help
- options简写:
-V
、-h
- 带params的options:
--path /Users/sam/Desktop/vue-test
3. 帮助文档
一个清晰的帮助文档,能方便开发者更好的使用脚手架成功。
帮助文档分为全局的帮助文档,和各个命令对应的帮助文档。
vue脚手架对应的全局的帮助文档:
- Usage
- Commands
- Options
Usage: vue <command> [options]
Options:
-V, --version output the version number
-h, --help output usage information
Commands:
create [options] <app-name> create a new project powered by vue-cli-service
add [options] <plugin> [pluginOptions] install a plugin and invoke its generator in an already created project
invoke [options] <plugin> [pluginOptions] invoke the generator of a plugin in an already created project
inspect [options] [paths...] inspect the webpack config in a project with vue-cli-service
serve [options] [entry] serve a .js or .vue file in development mode with zero config
build [options] [entry] build a .js or .vue file in production mode with zero config
ui [options] start and open the vue-cli ui
init [options] <template> <app-name> generate a project from a remote template (legacy API, requires @vue/cli-init)
config [options] [value] inspect and modify the config
outdated [options] (experimental) check for outdated vue cli service / plugins
upgrade [options] [plugin-name] (experimental) upgrade vue cli service / plugins
migrate [options] [plugin-name] (experimental) run migrator for an already-installed cli plugin
info print debugging information about your environment
Run vue <command> --help for detailed usage of given command.
各个命令对应的帮助文档:
- Usage
- Options
Usage: create [options] <app-name>
create a new project powered by vue-cli-service
Options:
-p, --preset <presetName> Skip prompts and use saved or remote preset
-d, --default Skip prompts and use default preset
-i, --inlinePreset <json> Skip prompts and use inline JSON string as preset
-m, --packageManager <command> Use specified npm client when installing dependencies
-r, --registry <url> Use specified npm registry when installing dependencies (only for npm)
-g, --git [message] Force git initialization with initial commit message
-n, --no-git Skip git initialization
-f, --force Overwrite target directory if it exists
--merge Merge target directory if it exists
-c, --clone Use git clone when fetching remote preset
-x, --proxy <proxyUrl> Use specified proxy when creating project
-b, --bare Scaffold project without beginner instructions
--skipGetStarted Skip displaying "Get started" instructions
-h, --help output usage information
还有很多,比如:
- 命令行交互
- 日志打印
- 命令行文字变色
- 网络通信:HTTP/WebSocket
- 文件处理
既然需要有这么多功能,业界肯定有成熟的第三方库来解决这些问题,在后面的文章中将会一一实现。
转载自:https://juejin.cn/post/7146828015383609375