前端开发过程中常见的CLI有:
create-react-app
vue-cli
webpack-cli
prettier-cli
基本复杂一点的工具都在集成CLI,为啥都要搞成CLI呢?
因为CLI可以提供更强大的功能:
通过命令搭配实现不同的功能
管理项目模版
启动本地服务
生成模版文件
对代码进行格式化
我们先搭建一个最简单的CLI来体验下,然后逐步实现复杂点的功能。
首先新建项目作为CLI源代码地址
mkdir cli-demo cd cli-demo npm init 复制代码
yargs文档配置:该插件将用户通过终端输入的参数解析成对象,可以配置各种参数。
yarn add yargs 复制代码
命令使用语法:
.command(cmd, desc, [builder], [handler]) 复制代码
下面的配置说明:
配置命令get
声明信息make a get HTTP request
并配置了参数url
信息
最后callback函数获取用户执行的参数
具体使用:编辑index.js
,第一行一定要加注释,表明运行在node环境下
#!/usr/bin/env node const yargs = require('yargs/yargs') const { hideBin } = require('yargs/helpers') yargs(hideBin(process.argv)) .command( 'get', 'make a get HTTP request', function (yargs) { return yargs.options({ url: { alias: 'u', describe: 'the URL to make an HTTP request to' } }) }, function (argv) { console.log("callback", argv.url) } ) .help() .argv 复制代码
执行命令,可以获取输入的参数
这里get就是定义的指令,url是指令下的key值,用--url输入,alias就是别名,用-u表示,后面跟要输入的参数。
接着我们发布下npm,然后一个CLI就完成了。
登陆npm仓库,没有的话去注册一个,地址
npm login 复制代码
选择一个中意的cli名字,查一下是否存在,这里我们起个名字cli-demo3
执行npm version patch && npm publish --registry=https://registry.npmjs.org
,不出意外的话,就发布成功了。
然后我们本地使用下,首先下载到本地,全局下载npm install -g cli-demo3
cli-demo3是我们前期测试使用写的CLI,后面继续使用我正常部署的CLI:u-amin-cli,原理是一样的
# 这里使用4版本,升级到5版本不再支持require方式导入 yarn add log-symbols@4.1.0 复制代码
使用方法
使用效果
# 这里使用4版本,升级到5版本不再支持require方式导入 yarn add chalk@4.1.2 复制代码
1、支持传入string,array和模版字符串
使用方法
console.log(chalk.blue("this is blue")) console.log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')); console.log(` CPU: ${chalk.red('90%')} RAM: ${chalk.green('40%')} DISK: ${chalk.yellow('70%')} `); 复制代码
使用效果
2、支持修改背景色、各种颜色格式、指定不同文本的颜色
使用方法
console.log(chalk.blue.bgRed.bold('Hello world!')); console.log(chalk.red('Hello', chalk.underline.yellowBright('world') + '!')); console.log(chalk.hex('#DEADED').underline('Hello, world!')) console.log(chalk.rgb(15, 100, 204).inverse('Hello!')) 复制代码
使用效果
3、支持自行封装一些颜色
使用方法
const error = chalk.bold.red; const warning = chalk.hex('#FFA500'); // Orange color console.log(error('Error!')); console.log(warning('Warning!')); 复制代码
使用效果
# 这里使用5版本,升级到6版本不再支持require方式导入 yarn add ora@5.4.1 复制代码
使用方法
const ora = require('ora'); const spinner = ora('Loading unicorns').start(); setTimeout(() => { spinner.color = 'yellow'; spinner.text = 'Loading rainbows'; }, 1000); 复制代码
使用效果
使用方法
var inquirer = require('inquirer'); inquirer .prompt([ { name: "templateType", type: "list", default: "vue", choices: [ { name: "React", value: "react", }, ], message: "Select the template type.", } ]) .then((answers) => { // Use user feedback for... whatever!! }) .catch((error) => { if (error.isTtyError) { // Prompt couldn't be rendered in the current environment } else { // Something else went wrong } }); 复制代码
使用效果
这样就可以给客户提示选择来处理逻辑。
使用方法
const download = require("download-git-repo"); download('direct:https://gitlab.com/flippidippi/download-git-repo-fixture.git#my-branch', 'test/tmp', { clone: true }, function (err) { console.log(err ? 'Error' : 'Success') }) 复制代码
还有很多类似的插件,来丰富cli的功能,根据需要添加即可
open 打开浏览器
yargs/commander 执行cli命令
get-port 获取当前端口号
启动文件index.js
const yargs = require('yargs/yargs') const { hideBin } = require('yargs/helpers') const config = require('./config') const yargsCommand = yargs(hideBin(process.argv)) config.forEach(commandConfig => { const { command, descriptions, options, callback } = commandConfig yargsCommand.command( command, descriptions, yargs => yargs.options(options), (argv, ...rest) => { callback(argv, ...rest); } ) }) yargsCommand.help().argv 复制代码
指令文件config.js
const commandOptions = [ { command: "create", descriptions: "拉取一个项目模版", options: { name: { alias: "n", type: "string", require: true, describe: "项目名称", }, }, callback: async (argv) => { create({name: argv.name}) } }] 复制代码
提取配置,就很清晰了
前端工程化:Prettier+ESLint+lint-staged+commitlint+Hooks+CI 自动化配置处理
上一步我们对配置进行了提取,接着根据配置生成使用文档,如下
使用方法
yarn add json2md@1.12.0 -D 复制代码
const json2md = require("json2md") // 按json2md需要的数据格式组合 const data = json2md([ { h1: "JSON To Markdown" } , { blockquote: "A JSON to Markdown converter." } ])) // 写入Readme.md文档 fs.writeFile(path.join(__dirname, "../Readme.md"), json2md(data), (err) => { if (err) throw err; console.log("update docs success"); }); 复制代码
{ command: "create", descriptions: "拉取一个项目模版", options: { name: { alias: "n", type: "string", require: true, describe: "项目名称", }, }, callback: async (argv) => { create({name: argv.name}) } } 复制代码
const map = { vue: "https://github.com/luchx/ECHI_VUE_CLI3.0.git", react: "git@github.com:richLpf/antd-template-demo.git#main" } 复制代码
1、inquirer提示用户选择对应的模版,具体可以看前面用法
2、通过download下载模版文件
module.exports = function downloadFromRemote(url, name) { return new Promise((resolve, reject) => { download(`direct:${url}`, name, { clone: true }, function (err) { if (err) { reject(err); return; } resolve(); }); }); }; 复制代码
3、通过ora在下载过程中展示loading
这是主要的下载逻辑,关于日志,我们可以更好的展示,也可以配置更复杂的命令:替换下载的项目名称,删除.git目录,修改package.json配置
前端在开发的过程中,总会遇到后端接口无法按时提供的情况,这种情况下有很多解决方案,常见的通过客户端生成模拟api,在项目中引入Mock。
这里我们通过CLI来实现一个更加简单好用的模拟方案
通过CLI启动一个或多个服务器,通过Express做路由转发本地的JSON文件
首先我们配置mock命令,设定参数type
、port
、create
分别代表API类型、启动Http服务器端口号,默认9000,create
是否自动生成接口数据JSON文件。
{ command: "mock", descriptions: "启动一个本地服务,模拟返回接口数据", options: { type: { alias: "t", type: "string", default: "action", describe: "选择API类型", choices: ['action', 'restful'] }, port: { alias: "P", type: "number", default: 9000, describe: "选择启动的端口号", }, create: { alias: "c", type: "boolean", default: false, describe: "如果mock目录不存在是否自动创建,默认不自动创建" }, }, callback: async (argv) => { mock({ ...argv }) } 复制代码
const app = express() app.use(bodyParser.json({limit: '50mb'})) app.use(express.urlencoded({ extended: true })); app.all('*', (req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); //访问控制允许来源:所有 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); //访问控制允许报头 X-Requested-With: xhr请求 res.header('Access-Control-Allow-Metheds', 'PUT, POST, GET, DELETE, OPTIONS'); //访问控制允许方法 res.header('X-Powered-By', 'nodejs'); //自定义头信息,表示服务端用nodejs res.header('Content-Type', 'application/json;charset=utf-8'); next(); }); const filePath = path.join(process.cwd(), `./mock/`) app.listen(port, () => console.log(`Mock api listening on port ${port}!`)); 复制代码
比如请求url为:
http://localhost:9000/acl 复制代码
请求体为:
{ Action: "GetUsers" } 复制代码
此时在CLI执行的目录,新建mock/acl/GetUsers.json
GetUsers.json内容为返回的json数据
{ "RetCode": 0, "Message": "this is error", "Data": [] } 复制代码
然后通过fs
模块读取json文件的数据,直接返回模拟的数据,因为是实时读取的,所以更新json数据不需要重启服务。主要逻辑如下
app.post('*', async(req, res) => { const key = req.params[0].substring(1) const { Action } = req.body const file = `${filePath}${key}/${Action}.json`; fs.readFile(file, 'utf-8', function(err, data) { if (err) { res.send(NotFoundResponse); } else { res.send(data); } }) }) 复制代码
比如请求url为:
http://localhost:9000/acl/users 复制代码
post请求体为:
{ limit: 10 } 复制代码
此时在CLI执行的目录,新建mock/acl/users/post.json
post.json内容为返回的json数据
{ "RetCode": 0, "Message": "get users", "Data": [] } 复制代码
如果是get请求,只需要添加get.json
就可以了。
然后同样通过fs
读取对应的json数据
app.all("*", async(req, res) => { const key = req.params[0] const method = req.method const file =`${filePath}${key}/${method}.json` console.log("file", file) fs.readFile(file, 'utf-8', function(err, data) { if (err) { res.send(NotFoundResponse); } else { res.send(data); } }) }) 复制代码
这样就完成了CLI启动一个模拟的http服务,用起来很方便,并且可以支持直接在项目中使用。
具体可以试试看u-admin-cli
对于大部分mock来说,复杂的配置是不需要的,这里仅仅是用了固定的json数据,我觉得就够用了,当然还可以自行处理数据,引入Mock规则,自行定义生成数据类型等
以上就是搭建一个CLI的过程,我们从最简单的开始构建了一个基础CLI,在这个基础上进行了交互优化,然后实际开发了CLI的两个功能:
1、通过CLI管理部门内的模版项目
2、通过CLI启动Http服务器,模拟接口生成
CLI地址:www.npmjs.com/package/u-a…
码字不易,欢迎点赞????,有问题请留言。
作者:前端中后台
链接:https://juejin.cn/post/7090001607596703758
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/127965.html
摘要:以下阅读将花费分钟前言日常开发中,我们都只专注在业务上的开发,拿起一套开箱即用的模板项目就直接开搞了,不知道大家有没有思考过,平时我们使用的脚手架里面到底做了什么,并且如果是自己来搭一套脚手架,应该怎么去搭呢在本博客中,将记录作者搭建脚手架 (以下阅读将花费10分钟) 前言 日常开发中,我们都只专注在业务上的开发,拿起一套开箱即用的模板项目就直接开搞了,不知道大家有没有思考过,平时我们...
摘要:后来经过排查你会发现是由于目前还没有版本。可以使用该方式解决。这就是我为什么不推荐你使用创建脚手架的原因此文的受众是想要进阶中级的初级前端人员。 最近在知乎看到一个问题,原问题如下: 很奇怪,为什么现在能找到自己手动创建vue脚手架的文章非常少,而且大家似乎对webpack4的热情并不高,对于想基于vue2.0+webpack4搭建一个脚手架的我来说资料真是少得可怜。难道现在一般的做...
摘要:如何在下搭建多模块单模块多路由骨架屏前言骨架屏的用户感知比更好,此前看过很多专栏以及文章,此次实践中还是遇到需要学习的部分。包括因为可能信息面不全,对插件源码进行了详细解读,希望对于将要在项目中搭建骨架屏的小伙伴们有所帮助。 如何在webpack+vue+vue-cli下搭建多模块/单模块多路由骨架屏 前言 骨架屏的用户感知比loading更好,此前看过很多专栏以及文章,此次实践中还是...
摘要:如何在下搭建多模块单模块多路由骨架屏前言骨架屏的用户感知比更好,此前看过很多专栏以及文章,此次实践中还是遇到需要学习的部分。包括因为可能信息面不全,对插件源码进行了详细解读,希望对于将要在项目中搭建骨架屏的小伙伴们有所帮助。 如何在webpack+vue+vue-cli下搭建多模块/单模块多路由骨架屏 前言 骨架屏的用户感知比loading更好,此前看过很多专栏以及文章,此次实践中还是...
摘要:之所以写这篇如何运用脚手架自动化构建出一个项目的大架构,主要是面向想入门的小伙伴。之前,我第一次接触,一直摸不着头脑,想在网上搜个接地气的教程都找不到。 WHY 之所以写这篇如何运用脚手架自动化构建出一个项目的大架构,主要是面向想入门vue的小伙伴。之前,我第一次接触vue,一直摸不着头脑,想在网上搜个接地气的教程都找不到。SO,我以如何搭建结构为开始,向想入门vue的童鞋们把我仅有的...
阅读 294·2024-11-07 18:25
阅读 130403·2024-02-01 10:43
阅读 873·2024-01-31 14:58
阅读 831·2024-01-31 14:54
阅读 82790·2024-01-29 17:11
阅读 3077·2024-01-25 14:55
阅读 1992·2023-06-02 13:36
阅读 3045·2023-05-23 10:26