node 構(gòu)建腳手架

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 去掉本地連接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容