一、基础脚手架思路
文件夹结构
project-cli
├─ templates // 自己定义的模板文件夹
│ ├─ 模板1
│ └─ 模板2
├─ bin
│ ├─ cli.js // 处理逻辑入口
├─ lib
│ ├─ create.js
├─ package-lock.json
└─ package.json
👉使用 :
npm i my-app-cliwow create <appName>
二、Summary
1. ESM 和 CMJ 中 __dirname __filname获取方式不一样
| ES module | Common Js | |
|---|---|---|
| 文件夹地址 | __filename | 1. import.meta 模块信息 2. import.meta.url 基于 file:// 协议的 绝对路径 3. 用 url 方法中的fileURLToPath(import.meta.url) 转化得到 |
| 文件地址 | __dirname | 4. 多一步 path.dirname() 把3中的值放入 |
__filename是执行文件的地址 带文件后缀
cwd是生成文件的根目录
2. ejs用法
<% %>流程控制标签<%= %>输出标签(原文输出 HTML 标签)<%- %>输出标签(HTML 会被浏览器解析)
- 直接
+拼接- 模板字符串
- ejs 优点:让js和html具有分开编写代码的功能pro版。会忽略所有代码 直接找到<% %>的地方开始替换。 所以ejs模板可单独放到html中。js里获取路径读取文件中的<% 就可以替换并输出
渲染方法:
ejs.render(str, data, options)ejs.renderFile(路径,填充的内容)
import ejs from 'ejs'
let result = ejs.render('这是一个水果 <%= fruit %>', {fruit:'apple'})
-------------------------------------------------------------------
// targetURL存在模板的路径 ;answers要替换成的数据;data返回的数据
ejs.renderFile(targetURL, answers).then(data => {
fs.writeFileSync(path.join(cwdUrl,file),data)
})
3. bin
- 工具包处的package.json
{
"bin": {
"fast-template": "./bin/cli.js"
// key作为使用方的node_modules下的bin的名字。value是执行的代码的路径
},
}
- 使用方 package.json 中配置
{
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"app-cli":"app-cli",
"project-cli":"fast-template"
// 前面是执行的快捷短语如yarn run project-cli ,value是去bin中找的包
},
}
4. commander
自定义命令指令的工具
<>必填,[]选填-缩写,--全称command('指令名称 <必填参数>')在命令后面传入的参数会被传入到 action 的回调函数以及 program.argv 数组中.option('-f, --force' , 'description')- 参数1:自定义标志
'短标,长标志'标志后可选加<>或者[] - 参数2:描述(可略)
- 参数3:默认值(可略)
- 参数1:自定义标志
.action((name,options)=>{})执行command后的回调.on('监听内容',()=>{})监听执行后面的回调
基本流程:
- 安装commander
npm install commander --save package.json中定义好bin:{"wow": "./bin/cli.js"}- 编写如下代码
#! /usr/bin/env node import { program } from 'commander' program // 定义命令和参数 .command('create <app-name>') .description('create a new project') .option('-f, --force', 'overwrite target directory if it exist') .action((name, option) => { // 打印执行结果 console.log('name:',name, 'options:',options) console.log(process.args); }) program // 配置版本号信息 .version(`v1.1`) .usage('<command> [option]') // 解析用户执行命令传入参数 program.parse(process.argv); - npm link
- bin中的key名字当做指令执行
5. fs-extra
fs模块的pro版,增加了对promise的支持
npm install fs-extra --save
6. chalk
终端增加颜色 npm install chalk
// 文本样式
console.log("project name is " + chalk.bold(name))
// 颜色
console.log("project name is " + chalk.green(name))
// 背景色
console.log("project name is " + chalk.bgRed(name))
// 使用RGB颜色输出
console.log("project name is " + chalk.rgb(4, 156, 219).underline(name));
console.log("project name is " + chalk.hex('#049CDB').bold(name));
console.log("project name is " + chalk.bgHex('#049CDB').bold(name))
7. node常用
let stat = fs.statSync()可以获取文件信息stat.isDirectory()判断是否是文件夹fs.mkdirSync(fileNamePath)创建文件夹fs.writeFileSync()写文件内容Path.resolve()把/作为根目录拼接 转为绝对路径。若没有/会自动加当前目录Path.join()连接path.relative(from,to)返回from到to两个块之间的相对路径