背景
在我司的所有项目中,有一类增删改查的页面出现率都是极其高的,我想做一个简单的脚手架来帮助大家能快速生成页面,在其上面进行具体业务修改进而提高开发效率。
选用依赖
开发命令行工具,TJ的"commander"是非常好的选择
日志,选用"winston3.x"和"dayjs"配合
模板,选用熟悉的"ejs"
"fs-extra",文件操作的封装与扩展
"jest",做一些简单的测试
其他,"eslint"语法检查以及插件,还有一些commit信息检查的支持
开始开发
大致目录结构
这类工具,首先是配置好用户的命令怎么去输入,那么第一步则是bin文件的开发:
// bin/index.js#!/usr/bin/env node'use strict';const program = require('commander');const packageJson = require('../package.json');const handle = require('../util/handle'); program .version(packageJson.version) .option('-c, --config <configPath>', 'required, the path of the JSON configuration') .option('-p, --path <filePath>', 'The path(include name) of the file you want to generate') .parse(process.argv);// 处理逻辑handle(program.config, program.path);
bin文件加上shebang头,告诉系统使用nodejs执行这一段脚本。
这里是让用户采用argv的形式传入参数执行文件,“commander”默认会-h生成帮助,我们同时需要编写每个option的帮助语句。这里我是让用户传入json配置路径(相对执行命令目录)与需要生成文件路径(相对执行命令目录,可不写,默认当前目录)
"commander"还支持其他命令,例如“command”模板语句加“command”的操作,具体文档我们可以在github/commanderjs中看到。
然后我们在package.json加上下面这一段
{ "bin": { "crud-init": "bin/index.js" } }
然后 我们就可以拿到参数开发业务逻辑了:
'use strict';const fs = require('fs');const fse = require('fs-extra');const path = require('path');const assert = require('assert');const log = require('./logger');const ejs = require('ejs');const exec = require('child_process').exec;/** * @param {string} configPath json配置路径 * @param {string} filePath 生成文件路径(相对执行命令目录,包含文件名) */module.exports = (configPath, filePath) => { assert(configPath, '-c <config> or --config <config>,The JSON configuration path must exist'); assert(!filePath || /\.vue$/.test(filePath), '-p <path> or --path <path>,The path must end with .vue'); const startTime = Date.now(); const cPath = path.join(process.cwd(), configPath); const fPath = path.join(process.cwd(), filePath || 'Unknown.vue'); let config; try { config = fse.readJsonSync(cPath); } catch (e) { assert.ifError(e); } const tplPath = path.join(__dirname, '../template/Crud.ejs'); const str = ejs.render(fs.readFileSync(tplPath, 'utf-8'), config); if (fse.pathExists(fPath)) { // 文件路径存在则先删除原文件 fse.removeSync(fPath); } // 确保文件被创建 fse.ensureFileSync(fPath); fs.writeFileSync(fPath, str); log.info(`生成位置:${fPath}`); const cmdStr = `${path.join(process.cwd(), 'node_modules/.bin/eslint')} --fix ${fPath}`; exec(cmdStr, err => { if (err) { log.warn('eslint修复失败,请检查是否在根目录执行命令以及eslint是否安装'); } log.info(`执行结束,用时${(Date.now() - startTime) / 1000}s`); }); };
这里我采用的是ejs模板生成了文件,然后执行当前工程的eslint进行修复。具体ejs模板怎么写在这就不贴出来了,大家如果还是做这个功能的话,按照自己实际情况去写即可。
以下是日志的简单配置,只是为了好看,不用日志工具用console也是可以的。
// util/logger.js'use strict';const { createLogger, format, transports } = require('winston');const { combine, colorize, timestamp, printf } = format;const day = require('dayjs');const myFormat = printf(info => { return `${day(info.timestamp).format('YYYY-MM-DD HH:mm:ss:SSS')} ${info.level}: ${info.message}`; });module.exports = createLogger({ level: 'info', format: combine( colorize(), timestamp(), myFormat ), transports: [ new transports.Console() ], });
调试的时候,使用 npm link 可以模拟全局安装,就能使用命令了。如果修改了package.json文件,则需要重新执行npm link
写了简单的测试执行handle函数
作者:CaanDoll
链接:https://www.jianshu.com/p/fd4aabcbb45a