node命令行工具之实现项目工程自动初始化的标准(2)

const commander = require('commander'); const chalk = require('chalk'); const packageJson = require('../package.json'); const log = console.log; function initCommand(){ commander.version(packageJson.version) .on('--help', ()=>{ log(chalk.green(' run testcli and edit the setting.')); }) .parse(process.argv); } module.exports = initCommand;

此时,项目结构如下:

npm-package-cli |-- bin |-- cli |-- src |-- command.js |-- index.js |-- package.json

然后在Creation.do方法内执行initCommand()即可生效。

// src/index.js Creation const initCommand = require('./command'); class Creation{ // other code do(){ initCommand(); } }

此时,运行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包的注意点

命令行工具中,使用的第三方工具包,都需要用--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工具时,才会自动安装这些依赖。

六、项目开源

我创作的npm-package-cli,是专门用于生成个人npm package项目的CLI工具。
生成的项目,囊括以下功能点:

支持TypeScrpt

mocha+chai自动化测试,支持使用TypeScript编写测试用例支持测试覆盖率

coverage支持eslint,包括对TypeScript的lint检查

Git commit规范提交

Git版本自动打标签(standard-version),更新CHANGELOG.md

输出的npm包

支持各种模块规范(AMD、CMD、CommonJS、ESModule)

CLI工具安装方式:

npm install -g npm-package-cli

开源仓库地址:https://github.com/wall-wxk/npm-package-cli

如果对你有所帮助,麻烦给个Star,你的肯定是我前进的动力~

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/cbd02910acb691bd26d80bc34a0e991e.html