标准模版创建(包含鉴权代码)
自定义规则创建
创建组件库
自动安装和启动
Git 自动化
云构建
项目自动发布
组件自动发布
开发脚手架的核心目标是:提升前端研发效能
创建项目 + 通用代码:埋点、HTTP请求、工具方法、组件库
git 操作:创建仓库、代码冲突、远程代码同步、创建版本、发布打 tag
构建 + 发布上线:依赖安装和构建、资源上传CDN、域名绑定、测试/正式服务器
将研发过程:
自动化:项目重复代码拷贝 / git 操作 / 发布上线操作
标准化:项目创建 / git flow / 发布流程 / 回滚流程
数据化:研发过程系统化、数据化,使得研发过程可量化
问题:jenkins、travis等自动化构建工具已经比较成熟了,为什么还需要自研脚手架?
不满足需求:jenkins、travis 通常在 git hooks 中触发,需要在服务端执行,无法覆盖研发人员本地的功能。如:创建项目自动化、本地 git 操作自动化等。
定制复杂:jenkins、travis 定制过程需要开发插件,其过程较为复杂,需要使用 java 语言,对前端同学不够友好。
脚手架本质是一个操作系统的客户端,它通过命令行执行,比如:
vue create vue-test-app
上面这条命令由 3 个部分组成:
·主命令:vue
·command:create
·command 的 param:vue-test-app
它表示创建一个 vue 项目,项目的名称为 vue-test-app,以上是较为简单的一个脚手架命令,但实际场景往往更加复杂,比如:
当前目录已经有文件了,我们需要覆盖当前目录下的文件,强制进行安装 vue 项目,此时我们就可以输入:
vue create vue-test-app --force
这里的 --force 叫做 option,用来辅助脚手架确认在特定场景下用户的选择(可以理解为配置)。还有一种场景:
通过 vue create 创建项目时,会自动执行 npm install 帮用户安装依赖,如果我们希望使用淘宝源来安装,可以输入命令:
vue create vue-test-app --force -r https://registry.npm.taobao.org
这里的 -r 也叫做 option,它与 --force 不同的是它使用 - ,并且使用简写,这里的 -r 也可以替换成 --registry,有的同学可能要问,为什么我知道这个命令,其实我们输入下面的命令就可以看到 vue create 支持的所有 options:
vue create --help
-r https://registry.npm.taobao.org 后面的 https://registry.npm.taobao.org 成为 option 的 param,其实 --force 可以理解为:--force true,简写为:--force 或 -f
脚手架的执行原理如下:
·在终端输入 vue create vue-test-app
·终端解析出 vue 命令
·终端在环境变量中找到 vue 命令
·终端根据 vue 命令链接到实际文件 vue.js
·终端利用 node 执行 vue.js
·vue.js 解析 command / options
·vue.js 执行 command
·执行完毕,退出执行
这里以 vue-cli 为例
·开发 npm 项目,该项目中应该包含一个 bin/vue.js 文件,并将这个项目发布到 npm
·将 npm 项目安装到 node 的 lib/node_modules
·在 node 的 bin 目录下配置 vue 软链接指向 lib/node_modules/@vue/cli/bin/vue.js
这样我们在执行 vue 命令的时候就可以找到 vue.js 进行执行
·为什么全局安装 @vue/cli 后会添加的命令为 vue ?
npm install -g @vue/cli
·全局安装 @vue/cli 时发生了什么
·为什么 vue 指向一个 js 文件,我们却可以直接通过 vue 命令直接去执行它?
·为什么全局安装 @vue/cli 后会添加的命令为 vue ?
答:@vue/cli 的 package.json 内配置的的
{
"bin": {
"vue": "bin/vue.js"
}
}
·全局安装 @vue/cli 时发生了什么
答:首先 npm 把 @vue/cli 包下载到 node/版本号/lib/node_modules 下。第二解析 cli/package.json 文件,根据 "bin"属性值 在node/bin目录下创建软链接。
·为什么 vue 指向一个 js 文件,我们却可以直接通过 vue 命令直接去执行它?
答:首先操作系统会在环境变量中找到 vue 命令有没有被注册,根据 "which vue"找到路径,执行这个文件。
第二 "#!/usr/bin/env node" 这句话会告诉操作系统在环境变量中找 node 命令。
第三 "ln -s /Users/sam/Desktop/vue-test/test.js imooc" 在 node/版本号/bin 目录下创建软链接。
掌握上节内容后,我们可以继续尝试回答以下2个问题:
·为什么说脚手架本质是操作系统的客户端?它和我们在PC上安装的应用/软件有什么区别?
答:node 本身是一个客户端。脚手架依赖 node 执行。和我们在 PC 上安装的应用/软件没有区别。
·如何为 node 脚手架命令创建别名?
答:方式一 对文件创建软链接。方式二 嵌套软链接。
·描述脚手架命令执行的全过程。
·创建 npm 项目
·创建脚手架入口文件,最上方添加:
#!/usr/bin/env node
·配置 package.json,添加 bin 属性
·编写脚手架代码
·将脚手架发布到 npm
·安装脚手架
npm install -g your-own-cli
·使用脚手架
your-own-cli
·分包:将复杂的系统拆分成若干个模块
·命令注册:
vue create
vue add
vue invoke
·参数解析:
vue command [options]
· options 全称:--version、--help
· options简写:-V、-h
· 带 params 的 options:--path /Users/sam/Desktop/vue-test
· 帮助文档:
global help
Usage
Options
Commands
command help
Usage
Options
还有很多,比如:
·命令行交互
·日志打印
·命令行字体变色
·网络通信:HTTP/WebSocket
·文件处理
等等......
mkdir imooc-test
cd imooc-test
npm init -y
code .
在 imooc-test 根目录下创建 bin/index.js
index.js 首行加入 #!/usr/bin/env node
package.json 中,加入
"bin": {
"imooc-test": "bin/index.js"
}
npm login
npm publish
注意:在 imooc-test 目录命令行中,执行 npm install -g imooc-test,会在 node/版本号/bin 中创建本地 imooc-test 文件的软链接。npm 这样做是为了方便本地调试。想要下载远程的文件,只需要跳出 imooc-test 目录即可。
情况一:
在 imooc-test 目录命令行中,执行 "npm link"。
会在 node/版本号/bin 中创建软链接指向 node/版本号/lib/node_modules/ ,node/版本号/lib/node_modules/ 指向 本地 imooc-test 目录。
情况二:
本地建一个包 imooc-test-lib,未发布到 npm 远程仓库上。
在 imooc-test-lib 目录命令行中,执行 "npm link",可以将 imooc-test-lib 软链接到 node/版本号/lib/node_modules/ 中。
再在 imooc-test 目录命令行中,执行 "npm link imooc-test-lib",就可以把 包 imooc-test-lib 引入 imooc-test/node_modules 中。
在 imooc-test/package.json 中,加入 "dependencies": {"imooc-test-lib": "^1.0.0"}
链接本地脚手架:
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:将当前项目中的库文件依赖移除
#!/usr/bin/env node
const lib = require('imooc-test-lib');
const argv = require('process').argv;
const command = argv[2];
const options = argv.slice(3);
let [option, param] = options
option = option.replace('--', '')
if (command) {
if (lib[command]) {
lib[command]()
} else {
console.log('无效的命令')
}
} else {
console.log('请输入命令')
}
npm publish