1、基本介紹
1、commander: 完整的 node.js 命令行解決方案。
2、download-git-repo:從節(jié)點(diǎn)下載并提取一個(gè)git存儲庫
3、figlet:制作歡迎頁面
4、chalk:改變控制臺輸出的樣式
5、clear:清除終端屏幕
6、handlebars: 可以高效地構(gòu)建語義化模板
7、inquirer: 常見的交互式命令行用戶界面的集合。
8、open: 打開諸如URL,文件,可執(zhí)行文件之類的東西
9、ora:加載動(dòng)畫
10、runjs:運(yùn)行腳本(新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 初始化項(xiàng)目
add 初始化增刪改查文件
temp 初始化基礎(chǔ)文件
sentry 接入sentry
qiankun 接入微前端
`)
})
program.parse(process.argv)
3、初始化項(xiàng)目
項(xiàng)目架構(gòu)是從git存儲庫拉取的。在這基礎(chǔ)上在配置自己所需要的功能。
注意:clone('url') 必須要加上direct
module.exports = async name => {
//打印頁面
clear()
const data = await figlet('zonst welcome')
log(data)
log('??創(chuàng)建項(xiàng)目' + name)
await clone('direct:https://git.xxxx/vue-admin-zonst#node-cli',name)
}
項(xiàng)目下載完成之后利用inquirer與用戶進(jìn)行交互,handlebars寫入模板
inquirer.prompt([{
type: 'input',
name: 'name',
message: '請輸入項(xiàng)目名稱'
},{
type: 'input',
name: 'description',
message: '請輸入項(xiàng)目簡介'
},{
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.添加功能
思路:將模板文件讀取,寫入對應(yīng)項(xiàng)目的文件中,使用runjs運(yùn)行命令
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);
}
})
})
}
/**
* 創(chuàng)建路徑
* @param {string} dir 路徑
*/
function mkdir(dir){
return new Promise((resolve, reject) => {
fs.mkdir(dir, err => {
if(err){
resolve(false);
}else{
resolve(true);
}
})
})
}
/**
* 路徑是否存在,不存在則創(chuàng)建
* @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; //拿到上級路徑
//遞歸判斷,如果上級目錄也不存在,則會代碼會在此處繼續(xù)循環(huán)執(zhí)行,直到目錄存在
let status = await dirExists(tempDir);
let mkdirStatus;
if(status){
mkdirStatus = await mkdir(dir);
}
return mkdirStatus;
}
module.exports = {
fscreateReadStream,
fscreateWriteStream
}
注意:如果是插入文件,那需要配置插入位置的標(biāo)記
5 發(fā)布npm
1、進(jìn)入npmjs.com官網(wǎng)
2、注冊npm賬號
3、在npm檢索是否有重命名的包名
4、將package.json中的name修改為發(fā)布的npm上的包名。與項(xiàng)目名稱無關(guān)
5、npm login (需要在npmjs的源上)
6、npm publish
7、npm unlink 去掉本地連接