1、基本介绍
1、commander: 完整的 node.js 命令行解决方案。
2、download-git-repo:从节点下载并提取一个git存储库
3、figlet:制作欢迎页面
4、chalk:改变控制台输出的样式
5、clear:清除终端屏幕
6、handlebars: 可以高效地构建语义化模板
7、inquirer: 常见的交互式命令行用户界面的集合。
8、open: 打开诸如URL,文件,可执行文件之类的东西
9、ora:加载动画
10、runjs:运行脚本(新tasksfile)
2.命令路口文件
"bin": {
"ff": "./bin/ff.js"
},
ff.js 使用 commander 来获取cmd命令,按模块将其指向不同的文件
list 是查看命令配置
#!/usr/bin/env node
const program = require('commander')
program.version(require('../package').version)
program
.command('init <name>')
.description('init project')
.action(require('../lib/init.js'))
program
.command('add <name>')
.description('create File')
.action(require('../lib/add.js'))
program
.command('temp <name>')
.description('create File')
.action(require('../lib/temp.js'))
program
.command('sentry')
.description('create File')
.action(require('../lib/sentry.js'))
program
.command('qiankun')
.description('create File')
.action(require('../lib/qiankun.js'))
program
.command('list')
.description('list')
.action(()=>{
console.log(`
init 初始化项目
add 初始化增删改查文件
temp 初始化基础文件
sentry 接入sentry
qiankun 接入微前端
`)
})
program.parse(process.argv)
3、初始化项目
项目架构是从git存储库拉取的。在这基础上在配置自己所需要的功能。
注意:clone('url') 必须要加上direct
module.exports = async name => {
//打印页面
clear()
const data = await figlet('zonst welcome')
log(data)
log('🚀创建项目' + name)
await clone('direct:https://git.xxxx/vue-admin-zonst#node-cli',name)
}
项目下载完成之后利用inquirer与用户进行交互,handlebars写入模板
inquirer.prompt([{
type: 'input',
name: 'name',
message: '请输入项目名称'
},{
type: 'input',
name: 'description',
message: '请输入项目简介'
},{
type: 'input',
name: 'author',
message: '请输入作者名称'
}]).then((answers)=>{
console.log(answers)
const packagePath = `${desc}/package.json`
const packageContent = fs.readFileSync(packagePath,'utf8')
const packageResult = handlebars.compile(packageContent)(answers)
fs.writeFileSync(packagePath,packageResult)
})
4.添加功能
思路:将模板文件读取,写入对应项目的文件中,使用runjs运行命令
run(`npm install`,{cwd:`${resolve('./')}/${desc}`})
run(`npm run lint:fix`,{cwd:`${resolve('./')}/${desc}`})
run(`npm run dev`,{cwd:`${resolve('./')}/${desc}`})
读写文件流common.js
const {promisify} = require('util')
const fs = require('fs')
const {resolve} = require('path')
const path = require('path')
/**
* 读取文件信息
* @param path 文件路径
* @returns {Promise<unknown>}
*/
function fscreateReadStream(path) {
return new Promise((resolve, reject) => {
const stream = fs.createReadStream(path,{encoding:"utf-8"})
stream.on("data",chunk=>{
resolve(chunk)
})
})
}
/**
* 写入文件信息
* @param path 文件路径
* @param fileName 文件名
* @param chunk 写入文件
* @returns {Promise<unknown>}
*/
async function fscreateWriteStream(path,fileName,chunk) {
await dirExists(path);
return new Promise((resolve, reject) => {
let ws=fs.createWriteStream(path+'/'+fileName,{
});
ws.write(chunk,err=>{
resolve(err)
});
})
}
/**
* 读取路径信息
* @param {string} path 路径
*/
function getStat(path){
return new Promise((resolve, reject) => {
fs.stat(path, (err, stats) => {
if(err){
resolve(false);
}else{
resolve(stats);
}
})
})
}
/**
* 创建路径
* @param {string} dir 路径
*/
function mkdir(dir){
return new Promise((resolve, reject) => {
fs.mkdir(dir, err => {
if(err){
resolve(false);
}else{
resolve(true);
}
})
})
}
/**
* 路径是否存在,不存在则创建
* @param {string} dir 路径
*/
async function dirExists(dir){
let isExists = await getStat(dir);
//如果该路径且不是文件,返回true
if(isExists && isExists.isDirectory()){
return true;
}else if(isExists){ //如果该路径存在但是文件,返回false
return false;
}
//如果该路径不存在
let tempDir = path.parse(dir).dir; //拿到上级路径
//递归判断,如果上级目录也不存在,则会代码会在此处继续循环执行,直到目录存在
let status = await dirExists(tempDir);
let mkdirStatus;
if(status){
mkdirStatus = await mkdir(dir);
}
return mkdirStatus;
}
module.exports = {
fscreateReadStream,
fscreateWriteStream
}
注意:如果是插入文件,那需要配置插入位置的标记
5 发布npm
1、进入npmjs.com官网
2、注册npm账号
3、在npm检索是否有重命名的包名
4、将package.json中的name修改为发布的npm上的包名。与项目名称无关
5、npm login (需要在npmjs的源上)
6、npm publish
7、npm unlink 去掉本地连接