预置命令
pnpm init
// 初始化一个新的 npm 项目
pnpm install commander inquirer chalk ini ora
//commander 参数解析- inquirer 交互式命令行工具 实现命令行选择功能 - chalk 改变控制台颜色 - ini 配置文件ini格式控制器 - ora 实现命令行loading
pnpm install @types/node typescript nodemon --save-dev
//安装ts类型将ts代码转义成js,nodemon-监控文件变化执行编译命令
文件
npm link
npm link 作用 npm link 临时链接到全局,将全局的包链接到本地,方便调试包,创建一个软链映射到全局下
bin文件夹-index.js入口文件
#!/usr/bin/env node 就是告诉系统可以在PATH目录中查找,然后使用Node运行。 存放脚手架的命令行执行脚本的地方,这个文件会解析用户在命令行中输入的参数,然后调用相关模块或功能来执行相应的操作。bin 文件夹是存放可执行文件的地方,用于解析命令行参数并执行相应的脚手架功能模块。
实现ts编译
tsconfig.json
{
"compilerOptions": {
"target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "ESNext" /* Specify what module code is generated. */,
"moduleResolution": "NodeNext" /* Specify how TypeScript looks up a file from a given module specifier. */,
"outDir": "bin",
"esModuleInterop": true,
"resolveJsonModule": true,
"rootDir": "src",
"baseUrl": "./src"
},
"include": ["src"],
"exclude": ["node_modules"]
}
加入命令 "build": "tsc",tsc tsc是 TypeScript 编译器的命令行工具。它会根据项目中的 TypeScript 源代码文件(通常是以 .ts 或 .tsx 扩展名结尾的文件)来生成相应的 JavaScript 文件。
使用nodemon解决反复npm run build 问题
npx nodemon
nodemon.json
{
"watch": ["src"],
"ext": "ts",
"exec": "tsc"
}
解决命令行的参数
process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。
#!/usr/bin/env node
import { program } from "commander";
import path from "path";
//解析用户传递参数
program.parse(process.argv);
console.log("runner ts");
console.log(path.join("a/b/c/d"));
ESM不支持把json文件当成模块进行引入,这在commonjs却可以,如果需要引入json文件,还需要借助createRequire函数:
获取外部package.json文件
代码:
#!/usr/bin/env node
import { program } from "commander";
import path from "path";
import { dirname, join } from "path";
import { createRequire } from "module";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const require = createRequire(import.meta.url);
const pkg = require(join(__dirname, "../package.json"));
//import.meta.url 返回模块的绝对的 `file:` URL
//解析用户传递参数
program.parse(process.argv); //直接解析用户参数
console.log("runner ts");
console.log(pkg);
pkg:pkg 变量使用 require() 函数来引入位于当前文件的上级目录下的 package.json 文件。我们使用 join() 函数将 __dirname 和相对路径 "../package.json" 结合起来,形成 package.json 的完整路径。然后,通过 require() 函数引入该 package.json 文件,并将结果赋值给 pkg 变量。这样,pkg 变量就包含了 package.json 文件的内容。
结果
name: 'my-cli-study',
version: '1.0.0',
description: '',
main: 'index.js',
bin: { 'my-cli': './bin/index.js' },
scripts: { build: 'tsc', test: 'echo "Error: no test specified" && exit 1'
},
type: 'module',
keywords: [],
author: '',
license: 'ISC',
dependencies: {
chalk: '^5.2.0',
commander: '^11.0.0',
ini: '^4.1.1',
inquirer: '^9.2.7',
ora: '^6.3.1'
},
devDependencies: {
'@types/node': '^20.3.2',
nodemon: '^2.0.22',
typescript: '^5.1.6'
}
}
命令开发
program对象提供了一系列方法和属性,可以用于定义命令、注册选项、解析参数等操作。通过操作program对象,可以实现对命令行程序的配置和控制。
1.通过脚手架创建一个项目 create(拉取仓库的模板,下载方式可以采用github gitlab gitee)
2.配置拉取的信息,配置系统文件 config
config实现
- 获取当前工作目录
- 判断是否存在
- 创建项目
utils实现
loading
ora是一个实现命令行loading效果的库。使用方法也很简单:
模板拉取
创建项目整体划分成下面步骤:
-
通过获取仓库的
API获取模板信息:Vue2 or Vue 3 -
将模板信息渲染为交互框,用户选择自己需要的模板
-
根据用户选择的模板,获取版本信息
-
将版本信息渲染成交互框,用户选择需要的版本
-
通过用户选取的模板及版本,下载对应模板到指定目录
-
将模板渲染为项目
自动化实现
configstore存储
创建子进程
node.js是基于单线程模型架构,这样的设计可以带来高效的CPU利用率,但是无法却利用多个核心的CPU,为了解决这个问题,node.js提供了child_process模块,通过多进程来实现对多核CPU的利用.
child_process 模块提供了以下 4 个方法用于创建子进程,并且每一种方法都有对应的同步版本:
-
spawn: 启动一个子进程来执行命令;
-
exec: 启动一个子进程来执行命令,与 spawn 不同的是,它有一个回调函数获知子进程的状况;
-
execFile: 启动一个子进程来执行可执行文件;
-
fork: 与 spawn 类似,不同点在于它创建 Node 的子进程只需指定要执行的 JavaScript 文件模块即可;
-
spawn 与 exec、execFile 不同的是,后两者创建时可以指定 timeout 属性设置超时时间,一旦创建的进程运行超过设定的时间将会被杀死;
-
exec 与 execFile 不同的是,exec 适合执行已有的命令,execFile 适合执行文件;
-
exec、execFile、fork 都是 spawn 的延伸应用,底层都是通过 spawn 实现的;
玩转 node 子进程 — child_process - 掘金 (juejin.cn)
Node.jsstdin,stdout, 和stdin
当我们运行一个Node.js程序时,会启动一个进程来执行该程序
stdout,stdin, 和stderr 是标准的流,当程序执行时,它们在程序和环境之间互连输入和输出通信通道。
每个进程初始化时都有三个开放的文件描述符,分别称为stdin 、stdout 、stderr 。
这三个文件描述符被统称为标准流。
为一个进程启动了一组三个标准流,我们可以通过Node.js中的process 对象访问它们。
process.stdin(0):标准输入流,它是程序的输入源。process.stdout(1):标准输出流,它是程序的输出源。process.stderr(2):标准错误流,用于由程序发出的错误信息和诊断。