banner
NEWS LETTER

脚手架的开发(一)

Scroll down

如何开发脚手架?

脚手架开发流程

  • 脚手架开发流程
    • 脚手架创建
      • npm init
    • 脚手架开发
      • 分包
      • 参数解析
    • 脚手架调试
      • npm link
    • 脚手架发布
      • npm publish

开发流程

  • 创建 npm 项目
  • 创建脚手架入口文件,最上方添加:
#!/usr/bin/env node
  • 配置 package.json,添加 bin 属性
  • 编写脚手架代码
  • 将脚手架发布到 npm

使用流程

  • 安装脚手架
npm install -g your-own-cli
  • 使用脚手架
your-own-cli

脚手架开发难点解析

  • 分包:将复杂的系统拆分成若干个模块
  • 命令注册:
vue create
vue add
vue invoke
  • 参数解析:
    • options 全称:--version--help
    • options 简写:-V-h
    • 带 params 的 options:--path /Users/sam/Desktop/vue-test

示例:

vue command [options] <params>
  • 帮助文档:
    • global help
      • Usage
      • Options
      • Commands

示例:vue 的帮助信息:

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.
  • command help
    • Usage
    • Options

vue create 的帮助信息:

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
  • 文件处理

等等……

链接本地脚手架:

cd your-cli-dir
npm link

链接本地库文件:

cd your-lib-dir
npm link
cd your-cli-dir
npm link your-lib

取消链接本地库文件:

cd your-lib-dir
npm unlink
cd your-cli-dir
# link存在
npm unlink your-lib
# link不存在
rm -rf node_modules
npm install -S your-lib

理解 npm link

  • npm link your-lib:将当前项目中 node_modules 下指定的库文件链接到 node 全局 node_modules 下的库文件
  • npm link:将当前项目链接到 node 全局 node_modules 中作为一个库文件,并解析 bin 配置创建可执行文件

理解 npm unlink

  • npm unlink:将当前项目从 node 全局 node_modules 中移除
  • npm unlink your-lib:将当前项目中的库文件依赖移除

开发脚手架(示栗)

先创建一个文件并进入文件。

mkdir test-cli && cd test-cli

初始化 npm

npm init -y

用代码编辑器打开 test-cli 项目之后,只有一个 package.json 文件,根目录创建 bin/index.js 文件目录及文件,在 index.js 添加 #!/usr/bin/env node

test-cli

打开 package.json 文件,添加如下句柄。

test-cli

登录 npm,注意设置 npm 的源,https://registry.npmjs.org/,注意是 https 不是 http,协议更新了,http 将无法登录。

npm login || npm adduser

发布 npm,注意,如果发布提示失败,注意包名和 package.json 中的 name 名称可以自定义一下,毕竟上面包太多了。

npm publish

npm publish

安装发布的依赖,记得环境变量和全局的概念

npm i cli-test -g

执行 cli-test,就会执行句柄进行输出。

本地调试

相当于增加了一个本地软链接,不全局安装也可以进行调试。

npm link

分包

把原项目放入一个文件夹,然后并行创建一个项目 cli-test-lib,执行 npm init -y

然后新建个 lib/index.js 文件夹及文件,

分包

接下来,需要让 cli-test 引用到 cli-test-lib 这个包,需要切换到 cli-test目录下,执行如下句柄。

npm link

可以看到下图,在 node_modules 下已经多了一个 cli-test-lib 文件夹,表示它引用成功。

软链

然后切换到 cli-test 目录下执行 npm link cli-test-lib 进行关联。、

🔔 注意:被引用包的 package.json 文件中, main: 对应的 lib/index.js 而不是默认的 index.js 文件,否则无法找到。
🔔 注意:发布上线前,在引用的 package.json 文件中,要在 dependencies 中增加 "cli-test-lib": "^1.0.0",否则会出现问题。

注册一个命令

比如去执行 cli-test init

cli-test init

可以发现,在命令句柄后面多了个 init,这里,利用 node 的原生模块,process 中的 args 可以拿到路径和命令信息。

注册命令

打印出来多了一个 init,既然这样,就可以利用 分包 特点,把命令变成方法进行执行,比如在 cli-test-lib/bin/index.js 中添加如下句柄。

module.exports = {
sum(a, b) {
return a + b
},

init() { ++++++
console.log('执行 init 流程')
},
}

然后在 cli-test/bin/index.js 中添加如下句柄。

注册命令

就可以看到如下效果。

注册命令

实现参数解析

延展上面的用栗,假设解析参数 --namevue-test

cli-test/bin/index.js 下,代码如图。

#!/usr/bin/env node

const lib = require('cli-test-lib')

// 注册一个命令 cli-test init

const argv = require('process').argv

const command = argv[2]

// 实现参数解析 --name 和 vue-test
// 剥离二级命令和 params
const options = argv.slice(3) ++++++++++
let [option, param] = options ++++++++++

// 处理二级命令
option = option.replace('--', '') ++++++++++

// 判断命令是否存在,是否有效
if (command) {
if (lib[command]) {
// 执行的时候将参数传递过去
lib[command]({ option, param }) +++++++++
} else {
console.log('无效的命令')
}
} else {
console.log('请输入命令')
}

cli-test-lib/bin/index.js 下,代码如图。

module.exports = {
sum(a, b) {
return a + b
},

init({ option, param }) { +++++++++++
console.log('执行 init 流程', option, param)
},
}

解析命令

如果还涉及到一些多态不确定的参数解析,就要耗费大量的时间处理,所以这块了解原理即可。

发布脚手架

需要解除本地分包的软链接,比如这里要解除 cli-test-lib

npm unlink

然后就可以进行发布,但是在发布的时候,需要更新版本号。

npm publish

然后在 cli-testpackage.json 中记得更新分包的版本号即可。

最后按照如上方式上钻更新 cli-test 最后发布即可,如果出现异常记得 rm -rf node_modules && npm unlink && npm publish,如果找不到版本记得更新 npm i -g,所以不基于框架开发脚手架,需要耗费比较多的心智成本。

我很可爱,请给我钱

其他文章