开发一个简单的脚手架
1.创建 npm
项目
首先创建一个文件夹,然后进入到该文件夹目录下,执行
npm init -y
2.创建脚手架入口文件bin/index.js
,在index.js
中添加如下代码
#!/usr/bin/env node
console.log('hello cli')
3.配置 package.json
,添加 bin
属性
{"name": "yj-study-create-cli","version": "1.0.1","description": "","bin": {"yj-study-create-cli": "bin/index.js"},"main": "index.js",...
}
4.将脚手架发布到 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, --versionoutput the version number-h, --help output usage information
Commands:create [options] <app-name>create a new project powered by vue-cli-serviceadd [options] <plugin> [pluginOptions] install a plugin and invoke its generator in an already created projectinvoke [options] <plugin> [pluginOptions]invoke the generator of a plugin in an already created projectinspect [options] [paths...] inspect the webpack config in a project with vue-cli-serviceserve [options] [entry]serve a .js or .vue file in development mode with zero configbuild [options] [entry]build a .js or .vue file in production mode with zero configui [options] start and open the vue-cli uiinit [options] <template> <app-name> generate a project from a remote template (legacy API, requires @vue/cli-init)config [options] [value] inspect and modify the configoutdated [options] (experimental) check for outdated vue cli service / pluginsupgrade [options] [plugin-name](experimental) upgrade vue cli service / pluginsmigrate [options] [plugin-name](experimental) run migrator for an already-installed cli plugininfo print debugging information about your environmentRun 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-gitSkip 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, --bareScaffold project without beginner instructions--skipGetStartedSkip displaying "Get started" instructions-h, --helpoutput usage information
还有很多,比如:
- 命令行交互
- 日志打印
- 命令行文字变色
- 网络通信:HTTP/WebSocket
- 文件处理
既然需要有这么多功能,业界肯定有成熟的第三方库来解决这些问题,在后面的文章中将会一一实现。
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取