itCommand();
}
}
此时,运行npg-cli --help
指令,就可以看到:
Usage: npg-cli [options]
Options:
-V, --version output the version number
-h, --help output usage information
run testcli and edit the setting.
4.6 获取用户输入配置信息
要获取用户输入的信息,需要借助工具inquirer
。
新建src/setting.js
文件,文件内容如下:
const inquirer = require('inquirer');
const fse = require('fs-extra');
function initSetting(){
let prompt = [
{
type: 'input',
name: 'projectName',
message: 'project name',
validate(input){
if(!input){
return 'project name is required.'
}
if(fse.existsSync(input)){
return 'project name of folder is exist.'
}
return true;
}
},
// other prompt
];
return inquirer.prompt(prompt);
}
module.exports = initSetting;
此时,项目结构如下:
npm-package-cli
|-- bin
|-- cli
|-- src
|-- command.js
|-- index.js
|-- setting.js
|-- package.json
然后在Creation.do
方法内执行initSetting()
即可生效。
// src/index.js Creation
const initCommand = require('./command');
const initSetting = require('./setting');
class Creation{
// other code
do(){
initCommand();
initSetting().then(setting => {
// 用户输入完成后,会得到全部输入信息的json数据 setting
});
}
}
这里,inquirer.prompt
方法装载好要收集的问题后,返回的是Promise
对象。收集完成之后,要在then
方法内拿到配置信息,以便进行下一步模板替换的操作。
4.7 模板文件替换输出
模板文件替换,要用到工具mem-fs
和mem-fs-editor
。
文件操作,要用到工具shelljs
。
新建src/output.js
文件,文件内容如下(删除了部分代码,以下只是示例,完整项目看最后分享链接):
const chalk = require('chalk');
const fse = require('fs-extra');
const path = require('path');
const log = console.log;
function output(creation){
return new Promise((resolve, reject)=>{
// 拿到配置信息
const setting = creation._setting;
const {
projectName
} = setting;
// 获取当前命令行执行环境所在文件夹
const cwd = process.cwd();
// 初始化文件夹path
const projectPath = path.join(cwd, projectName);
const projectResolve = getProjectResolve(projectPath);
// 新建项目文件夹
fse.mkdirSync(projectPath);
// copy文件夹
creation.copy('src', projectResolve('src'));
// 根据配置信息,替换文件内容
creation.copyTpl('package.json', projectResolve('package.json'), setting);
// 将内存中的文件,输出到硬盘上
creation._mfs.commit(() => {
resolve();
});
});
}
module.exports = output;
output
方法的作用:
- 新建项目文件夹
- 把模板文件读取出来,根据配置信息,进行替换(调用的是
mem-fs-editor
的copyTpl
方法)
- 拷贝其他文件
- 输出最终文件到硬盘上
这里最重要的一步,是调用mem-fs-editor
的方法后,要执行mem-fs-editor
的commit
方法,输出内存中的文件到硬盘上。
在Creation.do
方法中,调用output
方法即可输出新项目文件。
打开src/index.js
文件,文件内容增加如下方法:
// src/index.js Creation
const initCommand = require('./command');
const initSetting = require('./setting');
const output = require('./output');
class Creation{
// other code
do(){
initCommand();
initSetting().then(setting => {
// 用户输入完成后,会得到全部输入信息的json数据 setting
this._setting = Object.assign({}, this._setting, setting);
// 输出文件
output(this).then(res => {
// 项目输出完成
});
});
}
}
4.8 阶段小结
自动初始化一个项目的流程不外乎以下三点:
- 读取用户配置
- 读取模板文件
- 根据配置,编译模板文件,输出最终文件
命令行工具,是对这三点的有效整合,串连成一个规范的流程。
五、发布npm包的注意点
5.1 安装依赖包的方式
命令行工具中,使用的第三方工具包,都需要用--save
的方式安装。
体现在package.json
的表现是dependencies
字段:
"dependencies": {
"chalk": "^2.4.2",
"commander": "^3.0.0",
"fs-extra": "^8.1.0",
"inquirer": "^6.5.0",
"mem-fs": "^1.1.3",
"mem-fs-editor": "^6.0.0",
"shelljs": "^0.8.3"
},
这样,其他用户在安装你发布的CLI工具时,才会自动安装这些依赖。
5.2 .git