Yargs官方地址vue
存在三個參數
file: 文件夾以及模塊名(必填)
path: 文件存放路徑
type: 模板類型
command(cmd, desc, [builder], [handler])
用command方法建立了一個命令,將先前定義的參數放到command的bulider裏面。
[handler]處理傳參。
1.建立文件夾
2.建立文件
可以建立文件是不夠的,咱們須要文件內容是咱們定義好的模板內容,因此咱們先定義好模板。
ReactTemplat、VueTemplate: 是自定義模板,能夠根據本身的模板內容、結構來自定義。node
cli.js: 用來建立命令,而且將參數傳給start文件處理。react
start.js: 用來處理參數,建立文件夾及文件,利用process進程與用戶進行交互。git
handle.js: 處理文件的方法。github
node ./tools/cli add -h // 顯示幫助信息
Options:
--version Show version number [boolean]
-h Show help [boolean]
--file, -f create a file [required]
--path, -p file path [default: ""]
--type, -t file‘s type [choices: "vue", "react"] [default: "vue"]
Examples:
node tools/cli add -p views -f test -t vue 在views目錄下建立一個test模板
複製代碼
node tools/cli add -f test -p views -t vue
複製代碼
在views目錄下建立一個test模塊,模塊類型是vue。
新建模塊時會先判斷存放路徑是否存在該文件夾。bash
遇到重複的模塊可選是否須要覆蓋async
文件地址ide
const argv = require('yargs')
.command(
'add',
'create a file',
function(yargs) {
return yargs
.option('file', {
alias: 'f',
describe: 'create a file'
})
.option('path', {
alias: 'p',
describe: 'file path',
default: ''
})
.option('type', {
alias: 't',
describe: 'file‘s type',
choices: ['vue', 'react'], // 如今有兩個模板供選擇,能夠根據本身的項目狀況設計模板
default: 'vue'
})
.demandOption(['file'], 'Please provide file to work with this tool')
.example(
'node tools/cli add -p views -f test -t vue',
'在views目錄下建立一個test模板'
)
},
function(argv) {
// 根據參數,建立模板
start(argv)
}
)
.help('h').argv
複製代碼
const handel = require('./handle')
const colors = require('colors')
const path = require('path')
module.exports = async function(argv) {
argv.file = argv.file.toString()
const existPathFolder = await handel.existFolder(path.resolve(argv.path))
const fileName =
argv.file.substring(0, 1).toUpperCase() + argv.file.substring(1)
let className = ''
for (let i = 0; i < argv.file.length; i++) {
if (/[A-Z]/.test(argv.file[i])) {
className += '-'
}
className += argv.file[i].toLowerCase()
}
if (argv.path !== '') {
argv.path += '/'
}
const filePath = path.resolve(argv.path) + '/' + fileName
process.stdin.setEncoding('utf8')
const createFileData = {
filePath,
fileName,
className,
type: argv.type
}
// 不存在path的文件夾
if (!existPathFolder) {
console.warn(
colors.green(`是否建立 ${path.resolve(argv.path)} 文件夾?:y/n`)
)
process.stdin.on('data', async chunk => {
chunk = chunk.replace(/[\s\n]/, '')
if (chunk === 'y') {
// 建立path文件夾
await handel.createFolder(path.resolve(argv.path))
// 建立組件文件夾
await handel.createFolder(filePath)
// 建立文件
await handel.createFile(createFileData)
process.exit()
} else if (chunk === 'n') {
process.exit()
} else {
console.warn(colors.red('請輸入正確指令:y/n'))
process.exit()
}
})
} else {
// 判斷組件文件夾是否存在
const existFileFolder = await handel.existFolder(filePath)
if (existFileFolder) {
console.warn(colors.green(`${fileName}文件夾已存在,是否覆蓋?:y/n`))
process.stdin.on('data', async chunk => {
chunk = chunk.replace(/[\s\n]/, '')
if (chunk === 'y') {
// 建立組件文件夾
await handel.createFolder(filePath)
// 建立文件
await handel.createFile(createFileData)
process.exit()
} else if (chunk === 'n') {
process.exit()
} else {
console.warn(colors.red('請輸入正確指令:y/n'))
process.exit()
}
})
} else {
// 建立組件文件夾
await handel.createFolder(filePath)
// 建立文件
await handel.createFile(createFileData)
process.exit()
}
}
}
複製代碼
const fs = require('fs')
const colors = require('colors')
const path = require('path')
module.exports = {
existFolder: async function(path) {
// 判斷是否存在argv.path的文件夾
return new Promise(function(resolve, reject) {
return fs.exists(path, e => {
resolve(e)
})
})
},
/**
*建立文件夾
@param filePath 文件路徑
*/
createFolder: function(filePath) {
return new Promise(function(resolve, reject) {
fs.mkdir(filePath, function(err) {
if (err) {
if (err.errno === -2) {
console.log(colors.red('找不到目錄'))
} else if (err.errno === -17) {
}
} else {
console.log(colors.green('建立文件夾: '))
console.log(colors.underline(`${filePath}`))
}
resolve()
})
})
},
/**
* @param args:{
* filePath 文件路徑
* fileName 文件名
* className 樣式名
* type 文件類型
* }
*/
createFile: function({ filePath, fileName, className, type }) {
const data = {
fileName,
filePath,
className
}
// 模板路徑
switch (type) {
case 'vue':
data.templateFolderPath = path.join(__dirname, './VueTemplate')
break
case 'react':
data.templateFolderPath = path.join(__dirname, './VueTemplate')
break
default:
data.templateFolderPath = path.join(__dirname, './VueTemplate')
}
return new Promise(async (resolve, reject) => {
await this.readAndWiteFile(data, resolve)
})
},
/**
* 讀取模板內容而且寫到新建文件裏面
* @param args:{
* templateFolderPath 模板路徑
* fileName 文件名
* filePath 文件路徑
* className 樣式名字
* }
* @param resolve
*/
readAndWiteFile: function(
{ templateFolderPath, fileName, filePath, className },
resolve
) {
fs.readdir(templateFolderPath, 'utf8', (err, files) => {
if (err) {
console.log(colors.red(err))
return false
}
files.forEach(templateName => {
const FileName = templateName
.replace('TemplateName', fileName)
.replace('.txt', '')
// 1.建立文件
fs.createWriteStream(`${filePath}/${FileName}`)
// 2.讀取、寫入模板內容
const content = fs
.readFileSync(`${templateFolderPath}/${templateName}`)
.toString() // 讀取模板文件
.replace(/\${TemplateName}/g, FileName.split('.')[0])
.replace(/\${template-name}/g, className) // 替換模板內容
// 將templateName替換成對應的文件名
fs.writeFileSync(`${filePath}/${FileName}`, content, 'utf8')
console.log(colors.green('寫入文件: '))
console.log(colors.underline(`${filePath}/${FileName}`))
})
resolve()
})
}
}
複製代碼
這種方法比較繁瑣,下面優化了兩個版本工具
(1)命令: node tools2/cli add -f fileName學習
(2)提示選擇模板
(3)選擇放置位置,提供進入下一層,返回上一層操做
針對上面一旦出現深層路徑的話,操做會很繁瑣,因此提供動態選擇路徑,根據關鍵字提示路徑地址。
步驟
(1)命令: node tools3/cli
(2)填寫文件名
(3)提示選擇模板
(4)提示放置地址