包名 | 功能 |
---|---|
Commander | 用户入参解析,如 -help |
inquirer | 常见的交互式命令行用户界面的集合 |
download-git-repo | 在 git 中下载模板 |
chalk | 改变控制台的字体颜色 |
metalsmith | 读取所有文件,实现模板渲染 |
consolidate | 统一模板引擎 |
实现功能,输入命令行,脚手架名 指令 入参:
lwb-cli create myReact
mkdir lwb-cli
npm init
"bin": {
"lwb-cli": "./bin/www"
}
#! /usr/bin/env node
require('../src/main.js');
npm link
program
.command("create")
.alias("c")
.description("新建一个项目")
.action(() => {
console.log("create");
});
// 根据不同的动作,动态引入对应模块的文件
// path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
// process.argv 属性返回一个数组,就是用户在命令行中传入的参数。
require(path.resolve(__dirname, action))(...process.argv.slice(3));
program.version(version).parse(process.argv);
program.on('--help', () => {
console.log('Examples');
Reflect.ownKeys(actionsMap).forEach((action) => {
(actionsMap[action].examples || []).forEach((example) => {
console.log(` ${example}`);
});
});
});
module.exports = async (projectName) => {
console.log(projectName);
};
1、axios 2、github 的 API,获取当前组织中的所有仓库信息,https://api.github.com/orgs/项目名/repos
1、inquirer 询问式 2、ora loading 效果
const spinner = ora('fetching repo list');
spinner.start()
spinner.succeed()
const { repo } = await Inquirer.prompt({
name: 'repo',
type: 'list',
message: '请选择一个项目来创建模板', choices: repos, // 选择模式
});
const { promisify } = require('util');
const downLoadGit = require('download-git-repo');
downLoadGit = promisify(downLoadGit);
// 存储模板的位置
const downloadDirectory =
process.env[process.platform === "darwin" ? "HOME" : "USERPROFILE"]
let ncp = require('ncp');
ncp = promisify(ncp);
// 将下载的文件拷贝到当前执行命令的目录下
await ncp(target, path.join(path.resolve(), projectName));
module.exports = [
{
type: 'confirm',
name: 'private',
message: 'ths resgistery is private?',
}
]
"autor":"<%=author%>",
"description": "<%=description%>",
"license": "<%=license%>"
// 下载下来的文件,如果有ask文件: 就是个复杂的模板,需要用户选择 ,然后编译模板
if (!fs.existsSync(path.join(resultDirectory, "ask.js"))) {
// 拿到下载到的目录之后,直接copy到当前目录下即可 ncp
await ncp(resultDirectory, path.resolve(projectName));
chalkSuccess(`创建项目成功 请执行\n cd ${projectName}`);
process.exit();
} else {
// 1、让用户填信息
await new Promise((resolve, reject) => {
metalsmith(__dirname) //传入默认路径,默认遍历当前路径下的src文件夹
.source(resultDirectory)
//拷贝到用户指定目录下
.destination(path.resolve(projectName))
.use(async (files, metal, done) => {
const asks = require(path.join(resultDirectory, "ask.js"));
const userSelected = await Inquirer.prompt(asks);
const meta = metal.metadata();
Object.assign(meta, userSelected);
delete files["ask.js"];
done();
})
.use((files, metal, done) => {
const metaData = metal.metadata();
Reflect.ownKeys(files).forEach(async fileName => {
//处理带 <%的命令
if (fileName.includes("js") || fileName.includes("json")) {
let content = files[fileName].contents.toString();
// console.log("content: ", content)
if (content.includes("<%")) {
//渲染content
content = await render(content, metaData);
files[fileName].contents = Buffer.from(content);
}
}
});
done();
})
.build(err => {
if (err) {
chalkError(err);
reject();
} else {
chalkSuccess(`创建项目成功 请执行 cd ${projectName}`);
process.exit();
resolve();
}
});
}).catch({});
}
//查看npm路径、一般都是淘宝,修改为正式的
npm config get registry //查看
npm config set registry=http://registry.npm.org/ //设置
//第一次发布需要登录
npm login
//发布
npm publish