目前公司采用的項目結構是基于vue-cli腳手架,再在基礎上進行通用組件、業(yè)務組件的封裝和抽離,目前已經(jīng)比較完善和穩(wěn)定。但每次一個新的項目入廠,需要復制拷貝到新的項目目錄,比較繁瑣,通過搭建一個簡單的cli工具,那么幾個命令行就解決了。
其實大致的原理為:通過命令行來識別具體的信息,然后直接下載遠程git倉庫的代碼到本地機器。
搭建具體流程
- 創(chuàng)建項目文件夾tcy-cli
-
npm init初始化package.json - 安裝commander、download-git-repo依賴包
- 安裝修改控制臺輸出內容樣式的chalk、好看的加載圓圈效果ora
非必選 - 編寫相關腳手架命令行識別代碼
- 發(fā)布到npm
安裝包的時候,不要使用
--save-dev,因為包的依賴信息會放在devDependencies中,這樣在全局安裝腳手架的時候,不會安裝依賴包,要使用--save
commander可以對命令行做解析的庫,可以解析我們在命令行輸入,如tcy-cli init <projectName>
inquirer是常規(guī)交互式命令行用戶接口的集合,提供給 Node.js 一個方便嵌入,漂亮的命令行接口,功能有簡化詢問終端用戶問題,解析,驗證答案,提供錯誤反饋等等
download-git-repo可以下載git倉庫的代碼
具體代碼
#! /usr/bin/env node
const program = require('commander');
const download = require('download-git-repo')
const inquirer = require('inquirer')
const chalk = require('chalk')
const ora = require('ora')
const fs = require('fs')
const spinner = ora(chalk.yellow('Downloading template ...'))
const Version = '1.1.7'
// 修改項目package.json
function setPackage(projectName, answers) {
const packagePath = `${projectName}/package.json`
const packageJson = fs.readFileSync(packagePath, 'utf-8')
const packageResult = JSON.stringify(Object.assign(null, JSON.parse(packageJson), answers), null, 4)
fs.writeFileSync(packagePath, packageResult)
}
// 修改項目名稱配置文件
function setProjectName(projectName, fullName, shortName) {
const configPath = `${projectName}/src/conf/index.js`;
const str =
`// 項目全稱
const FullName = '${fullName}'
// 項目簡稱
const ShortName = '${shortName}'
export {
FullName,
ShortName
}
`
fs.writeFileSync(configPath, str)
}
// 設置空業(yè)務路由
function setEmptyRouterMap(projectName) {
const routerPath = `${projectName}/src/router/asyncRouterMap.js`
const str =
`// 業(yè)務路由表
export const asyncRouterMap = []
`
fs.writeFileSync(routerPath, str)
}
// 名稱校驗
function validateName(val) {
if(/^[\u4e00-\u9fa5]+$/.test(val)) {
return true
} else {
return "name must be chinaese"
}
}
// 問答內容
const promptList = [
// 項目全稱
{
type: 'input',
message: 'please set project fullname',
name: 'fullName',
validate: validateName
},
// 項目簡稱
{
type: 'input',
message: 'please set project shortname',
name: 'shortName',
validate: validateName
},
// 是否需要初始演示路由
{
type: 'list',
message: 'do you need a example router:',
name: 'router',
default: 'no',
choices: [
"no",
"yes"
]
}
]
program.version(Version, '-v, --version')
.command('init <projectName>')
.action((projectName) => {
inquirer.prompt(
promptList
).then(answers => {
spinner.start()
download('github:tianzhu1992/blocks-admin-vue', projectName, (err) => {
spinner.succeed()
const {fullName, shortName, router} = answers
// 設置package.json的名稱與版本號
setPackage(projectName, {name: projectName, version: Version})
// 修改項目名稱信息
setProjectName(projectName, fullName, shortName)
// 設置靜態(tài)初始路由
if(router === 'no') {
setEmptyRouterMap(projectName)
}
// 下載代碼成功/失敗提示
console.log(err ? chalk.red('Something Wrong In Download Template') : chalk.green('Download Template Success'))
})
});
})
program.parse(process.argv);
-
#! /usr/bin/env node是執(zhí)行這個文件時使用node方式執(zhí)行 -
program.version是解析別人輸入tcy-cli -v或tcy-cli --version時輸出的版本號 -
command指定和解析用戶輸入的信息,通過<projectName>來匹配相應的輸入信息 -
action是根據(jù)解析的輸入信息來獲取倉儲并在回調執(zhí)行接下來的任務 -
inquirer.prompt根據(jù)定義的問題來收集用戶填寫的內容,并在回調的形參answers中以鍵值對的形式展現(xiàn) -
download的第一個參數(shù)下載地址不是填我們git的網(wǎng)址,按照上述的格式填就行,第二個參數(shù)是生成的項目名,第三個參數(shù)是錯誤的回調執(zhí)行函數(shù),如果沒有錯誤信息,則表示執(zhí)行成功
發(fā)布到npm
首先得需要一個npm賬號,如沒有,利用郵箱注冊下https://www.npmjs.com/
登錄賬號
npm login
發(fā)布到npm
npm publish