前端脚手架搭建
文件目录结构
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文件中的版本号