本片博客转载:教你从零开始搭建一款前端脚手架工具 - SegmentFault 思否
需要详细了解的可以看原文档,这里我只是做个记录,方便自己以后查找文档
1、首先新建一个项目,并进行初始化
npm init -y
2、在生成的package.json文件中写入依赖并执行npm install
"dependencies": {
"chalk": "^1.1.3",
"co": "^4.6.0",
"co-prompt": "^1.0.0",
"commander": "^2.9.0"
}
npm install
3、接着在根目录下创建一个bin文件夹,在里面创建一个无后缀名的scion文件,该文件是整个脚手架的入口文件,在里面写入代码,以下有四种方法,分别是增加,删除,初始化项目和查看项目,add、del、list、init
#!/usr/bin/env node --harmony
'use strict'
// 定义脚手架的文件路径
process.env.NODE_PATH = __dirname + '/../node_modules/'
const program = require('commander')
// 定义当前版本
program
.version(require('../package').version )
// 定义使用方法
program
.usage('<command>')
program
.command('add')
.description('Add a new template')
.alias('a')
.action(() => {
require('../command/add')()
})
program
.command('list')
.description('List all the templates')
.alias('l')
.action(() => {
require('../command/list')()
})
program
.command('init')
.description('Generate a new project')
.alias('i')
.action(() => {
require('../command/init')()
})
program
.command('delete')
.description('Delete a template')
.alias('d')
.action(() => {
require('../command/delete')()
})
program.parse(process.argv)
if(!program.args.length){
program.help()
}
commander
的具体使用方法在这里就不展开了,可以直接到官网去看详细的文档。
然后在终端node scion,看见以下信息说明入口文件已经编写完成了。
Usage: scion <command>
Commands:扫描二维码关注公众号,回复: 14872096 查看本文章add|a Add a new template
list|l List all the templates
init|i Generate a new project
delete|d Delete a templateOptions:
-h, --help output usage information
-V, --version output the version number
4、在项目根目录下建立\command
文件夹,专门用来存放命令处理文件。
在根目录下建立templates.json
文件并写入如下内容,用来存放模版信息:
{"tpl":{}}
进入command并新建add.js
"use strict";
const co = require("co");
const prompt = require("co-prompt");
const config = require("./templates");
const chalk = require("chalk");
const fs = require("fs");
module.exports = () => {
co(function* () {
// 分步接收用户输入的参数
let tplName = yield prompt("Template name: ");
let gitUrl = yield prompt("Git https link: ");
let branch = yield prompt("Branch: ");
// 避免重复添加
if (!config.tpl[tplName]) {
config.tpl[tplName] = {};
config.tpl[tplName]["url"] = gitUrl.replace(/[\u0000-\u0019]/g, ""); // 过滤unicode字符
config.tpl[tplName]["branch"] = branch;
} else {
console.log(chalk.red("Template has already existed!"));
process.exit();
}
// 把模板信息写入templates.json
fs.writeFile(
__dirname + "/./templates.json",
JSON.stringify(config),
"utf-8",
(err) => {
if (err) console.log(err);
console.log(chalk.green("New template added!\n"));
console.log(chalk.grey("The last template list is: \n"));
console.log(config);
console.log("\n");
process.exit();
}
);
});
};
command下新建delete.js
"use strict";
const co = require("co");
const prompt = require("co-prompt");
const config = require("./templates");
const chalk = require("chalk");
const fs = require("fs");
module.exports = () => {
co(function* () {
// 接收用户输入的参数
let tplName = yield prompt("Template name: ");
// 删除对应的模板
if (config.tpl[tplName]) {
config.tpl[tplName] = undefined;
} else {
console.log(chalk.red("Template does not exist!"));
process.exit();
}
// 写入template.json
fs.writeFile(
__dirname + "/./templates.json",
JSON.stringify(config),
"utf-8",
(err) => {
if (err) console.log(err);
console.log(chalk.green("Template deleted!"));
console.log(chalk.grey("The last template list is: \n"));
console.log(config);
console.log("\n");
process.exit();
}
);
});
};
在command下新建init.js
"use strict";
const exec = require("child_process").exec;
const co = require("co");
const prompt = require("co-prompt");
const config = require("./templates");
const chalk = require("chalk");
module.exports = () => {
co(function* () {
// 处理用户输入
let tplName = yield prompt("Template name: ");
let projectName = yield prompt("Project name: ");
let gitUrl;
let branch;
if (!config.tpl[tplName]) {
console.log(chalk.red("\n × Template does not exit!"));
process.exit();
}
gitUrl = config.tpl[tplName].url;
branch = config.tpl[tplName].branch;
// git命令,远程拉取项目并自定义项目名
let cmdStr = `git clone ${gitUrl} ${projectName} && cd ${projectName} && git checkout ${branch}`;
console.log(chalk.white("\n Start generating..."));
exec(cmdStr, (error, stdout, stderr) => {
if (error) {
console.log(error);
process.exit();
}
console.log(chalk.green("\n √ Generation completed!"));
console.log(`\n cd ${projectName} && npm install \n`);
process.exit();
});
});
};
在command下新建list.js
"use strict";
const config = require("./templates");
module.exports = () => {
console.log(config.tpl);
process.exit();
};
5、为了可以全局使用,我们需要在package.json
里面设置一下:
"bin": {
"scion": "bin/scion"
},
6、本地调试的时候,在根目录下执行
npm link
即可把scion
命令绑定到全局,以后就可以直接以scion
作为命令开头而无需敲入长长的node scion
之类的命令了。
详情请看原文档哈,此博客仅是记录实现过程。