欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端脚手架搭建

程序员文章站 2022-03-30 11:41:27
...

文件目录结构

dpy-cli
	bin
		index.js
	command
		add.js
		delete.js
		list.js
		init.js
package.json
templates.json

第一步
新建文件夹dpy-cli(自定义)然后在当前文件夹下运行cmd命令 npm init初始化package.json文件,并在package.json文件中新增bin字段,例如:

"bin": {
    "dpy": "bin/index.js"
  } //dpy是你要运行的命令

第二步
编写入口文件bin/index.js

#!/usr/bin/env node  //这一行一定要写,否则运行 dpy 命令报错
process.env.NODE_PATH = __dirname // 脚手架下载到的路径
const program = require("commander")
const chalk = require("chalk")
const ora = require("ora")
program.version(require("../package").version)
program.usage("<command>")
program
.command("add")
.alias("a")
.description(chalk.yellow("Add a new template"))
.action(() => {
    require("../command/add.js")()
})
program
.command("init")
.alias("i")
.description(chalk.yellow("Init a new project"))
.action(() => {
    require("../command/init.js")()
})
program
.command("delete")
.alias("d")
.description(chalk.yellow("Delete a template"))
.action(() => {
    require("../command/delete.js")()
})
program
.command("list")
.alias("l")
.description(chalk.yellow("List all templates"))
.action(() => {
    require("../command/list.js")()
})

program.parse(process.argv)
if(!program.args.length) {
    program.help()
}

运行npm link命令将自定义的命令绑定到全局(我的命令是dpy)否则找不到命令

PS D:\dpy-cli> npm link
npm WARN [email protected] No repository field.

audited 48 packages in 3.373s
found 0 vulnerabilities

C:\usr\local\dpy -> C:\usr\local\node_modules\dpy-cli\bin\index.js
C:\usr\local\node_modules\dpy-cli -> D:\dpy-cli
PS D:\dpy-cli>

运行dpy命令如下所示:

PS D:\dpy-cli> dpy
Usage: index <command>

Options:
  -V, --version  output the version number
  -h, --help     output usage information

Commands:
  add|a          Add a new template
  init|i         Init a new project
  delete|d       Delete a template
  list|l         List all templates
PS D:\dpy-cli>

第三步
编写command文件夹下的四个js命令文件
add.js文件代码如下:

const co = require("co")
const prompt = require("co-prompt")
const chalk = require("chalk")
const fs = require("fs")
const ora = require("ora")
const logSymbols = require("log-symbols")
const config = require("../templates")

module.exports = () => {
    co(function *() {
        let tplName = yield prompt(chalk.green("模板名称:"))
        let gitUrl = yield prompt(chalk.green("git地址:"))
        let branch = yield prompt(chalk.green("分支:"))
        const spinner = ora(`${chalk.cyan('正在添加模板...\n')}`).start();
        if(!config.tpl[tplName]) {
            config.tpl[tplName] = {}
            config.tpl[tplName]["url"] = gitUrl.replace(/[\u0000-\u0019]/g, "")
            config.tpl[tplName]["branch"] = branch
        } else {
            console.log(logSymbols.info, chalk.magenta("\u1f923" + "Template has already exit!!"))
            process.exit()
        }
        if(tplName === "" || gitUrl === "") {
            console.log(logSymbols.error\u1f639, chalk.red("\u1f639" + "模板名称和git地址不能为空!"))
            process.exit()
        }

        fs.writeFile(__dirname + "/../templates.json", JSON.stringify(config), "utf-8", (err) => {
            if(err) {
                console.log(err)
                process.exit()
            } else {
                console.log(logSymbols.success, chalk.green("\u263a" + "New template added! \n"))
                console.log(chalk.grey("The last template list is: \n"))
                console.log(config)
                process.exit()
                
            }
        })
    })
}
PS D:\dpy-cli> dpy add
模板名称:a
git地址:a
分支:a
- 正在添加模板...
√ ☺New template added! 

The last template list is: 

{ tpl:
   { first: { url: 'https://github.com/hellodpy/first.git', branch: '' },
     f: { url: 'f', branch: 'f' },
     a: { url: 'a', branch: 'a' } } }
PS D:\dpy-cli>

delete.js文件代码如下:

const co = require("co")
const prompt = require("co-prompt")
const chalk = require("chalk")
const fs = require("fs")
const ora = require("ora")
const logSymbols = require("log-symbols")
const exec = require("child_process").exec
const config = require("../templates")
const path = require('path');
let rootPath = path.resolve(__dirname,'..'); //代码文件的根路径

module.exports = () => {
    
    co(function *() {
        let tplName = yield prompt(chalk.green("模板名称:"))
        const spinner = ora(`${chalk.cyan('正在删除对应的模板... \n')}`).start();
        if(config.tpl[tplName]) {
            config.tpl[tplName] = undefined
        } else {
            console.log(logSymbols.error, chalk.red("Template does not exit!!"))
            process.exit()
        }
        
        let delPath = rootPath + '\\' + `${tplName}`
        
        delDir(delPath) //删除下载的模板
        
        fs.writeFile(__dirname + "/../templates.json", JSON.stringify(config), "utf-8", (err) => {
            if(err) {
                console.log(err)
                process.exit()
            } else {
                console.log(logSymbols.success, chalk.green("\u263a" + "Template deleted! \n"))
                console.log(chalk.grey("The last template list is: \n"))
                console.log(config)
                console.log("\n")
                process.exit()
                
            }
        })
    })
}


function delDir(path){
    let files = [];
    if(fs.existsSync(path)){
        files = fs.readdirSync(path);
        files.forEach((file, index) => {
            let curPath = path + "/" + file;
            if(fs.statSync(curPath).isDirectory()){
                delDir(curPath); //递归删除文件夹
            } else {
                fs.unlinkSync(curPath); //删除文件
            }
        });
        fs.rmdirSync(path);
    }
}
PS D:\dpy-cli> dpy d
模板名称:a
- 正在删除对应的模板... 
√ ☺Template deleted! 

The last template list is: 

{ tpl:
   { first: { url: 'https://github.com/hellodpy/first.git', branch: '' },
     f: { url: 'f', branch: 'f' },
     a: undefined } }


PS D:\dpy-cli>

list.js文件代码如下:

const config = require("../templates")
const chalk = require("chalk")
module.exports = () => {
    const templates = Object.keys(config.tpl)
    templates.map(item => {
        console.log(chalk.green("模板名称:") + item + "\n")
    })
    process.exit()
}
PS D:\dpy-cli> dpy list
模板名称:first

模板名称:f

PS D:\dpy-cli>

init.js文件代码如下:
const co = require(“co”)
const prompt = require(“co-prompt”)
const chalk = require(“chalk”)
const fs = require(“fs”)
const ora = require(“ora”)
const logSymbols = require(“log-symbols”)
const exec = require(“child_process”).exec
const config = require("…/templates")

module.exports = () => {
co(function *() {
let tplName = yield prompt(chalk.green(“模板名称:”))
let projectName = yield prompt(chalk.green(“项目名称:”))
let branch
let gitUrl
const spinner = ora(${chalk.cyan('正在创建项目...\n')}).start();
if(!config.tpl[tplName]) {
console.log(logSymbols.error, chalk.red("\n 选择模板不存在"))
process.exit()
}

    gitUrl = config.tpl[tplName].url
    branch = config.tpl[tplName].branch

    // let cmdStr = `git clone ${gitUrl} ${projectName} && cd ${projectName} && git checkout ${branch}`
    let cmdStr = `git clone ${gitUrl}`
    
    exec(cmdStr, (error, stdout, stderr) => {
        
        if(error) {
            console.log(error)
            process.exit()
        } else {
            spinner.succeed()
            console.log(logSymbols.success, chalk.green("\u263a" + "项目创建成功"))
            process.exit()
            
        }
    })
})

}

PS D:\dpy-cli> dpy init
模板名称:first
项目名称:first
√ 正在创建项目...

√ ☺项目创建成功
PS D:\dpy-cli>

我的templates.json文件中的内容如下:

{
    "tpl":{
        "first":{
            "url":"https://github.com/hellodpy/first.git",
            github上的模板地址,你自己可以在github上增加个仓库进行模拟下载
            "branch":""
        },
        "f":{
            "url":"f",
            "branch":"f"
        }
    }
}

最后把文件夹上传到npm官网(运行npm login登录命令,运行npm publish上传命令),就可以用npm install 包名就可以下载上传的脚手架到本地了(只有注册了npm官网的账号才能上传)

注意:
如果公司是封闭式开发,在公司运行git clone 项目地址时,需要输入用户名和密码,此脚手架没有写此功能,所以下载模板地址需要权限时dpy init会不成功。

脚手架编辑后再上传npm官网时需要更改package.json文件中的版本号