当前位置:网站首页>Cook a delicious cli
Cook a delicious cli
2022-06-24 10:53:00 【Mr egg】
Write at the top , I really want to write a recipe , Suffer from limited cooking power , So the title is a lie , ha-ha ^_~
Let's talk about command line tools today ( namely CLI:command-line interface, All of the following will use CLI Instead of long command line tool terms ) Development of .
After reading this article , You'll develop a CLI Have a more comprehensive understanding of .
You can also collect this article , When you want to develop a CLI when , Come back and turn it over , Always find what you want .
Daniel : Peanut Cola is ready , Wait for the start .
Heller , This is the beginning ,Let's go! <( ̄︶ ̄)GO!
> Take the first step : Initialize project
Create an empty project directory ( The next step is to cook-cli For example , So here we call it cook-cli), Then hit the command in the directory to initialize , The process is as follows :
$ mkdir cook-cli $ cd cook-cli $ npm init --yes
adopt npm init command , The directory will be initialized to a Node.js project , It will be cook-cli Generate under directory package.json file .
Add --yes Will automatically answer all questions asked during initialization , You can try to get rid of this parameter , Answer one question by one .
> Get through the main line :CLI Skeletal code
The project has been completed , Next we add skeleton code , Give Way CLI Fly for a while .
- Implementer
We created src/index.js file , It is responsible for the realization of CLI The functional logic of , It's practical work . The code is as follows :
export function cli(args) {
console.log('I like cooking');
}- spokesperson
Then create a bin/cook file , It is CLI The executable entry file for , yes CLI Spokesperson in the executable environment . The code is as follows :
#!/usr/bin/env node
require = require('esm')(module /*, options*/);
require('../src').cli(process.argv); Carefully you will find that esm This module , Its function is to let us in js Use... Directly in the source code ECMAScript modules Specification loading module , I.e. direct use import and export. above src/index.js Can write directly in the code of export Thanks to this module .
( Please run... In the project root directory npm i esm To install the module )
- Official announcement
We have spokesmen , But we have to publicize it . So in package.json add bin Statement of , Announce the existence of spokesmen . as follows :
{
...
"bin": {
"cook": "./bin/cook"
},
...
}> Rehearsal at all times : Local operation and debugging
stay CLI Before coming out , Local development debugging is essential , So it is very necessary to debug conveniently .
Daniel : Development Web application , I can debug the function through the browser . that CLI Yesterday ?
CLI It runs at the terminal , So we need to register it as a local command line first . The method is very simple , Run the following command in the root directory of the project :
$ npm link
This command registers a... In the local environment cook CLI, And link its execution logic code to your project directory , So every time you save a change, it will take effect immediately .
Try to run the following command :
$ cook
Daniel :Nice! But I have another question , I want to vscode Set breakpoints to debug , Sometimes it's easier to troubleshoot
You're right . The method is also very simple , stay vscode Add the following configuration , Path is : debugging > Add the configuration . According to the actual command parameters to be debugged , modify args The value of the can .
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Cook",
"program": "${workspaceFolder}/bin/cook",
"args": ["hello"] // Fill in the parameters you want to debug
}
]
}> Intention recognition : Enter parameter resolution
Insert a little interlude : Although you may often come into contact with all kinds of CLI, But it's still necessary to CLI A brief introduction to some of the terms involved :
- command (command) And sub orders (subcommand)
# cook It's an order $ cook # start That is to say cook Of Sons command $ cook start
- Command options (options)
# -V For shorthand mode (short flag) The option to ( Be careful : Only one letter , Multiple letters represent multiple options ) $ cook -V # --version For full write mode (long name) The option to $ cook --version
- Command parameter (argument)
# source.js and target.js All for cp Arguments to the command $ cp source.js target.js
Actually , Subcommands are also parameters of commands
Ok, From the above introduction , We want to achieve one CLI, Right in ( Include subcommand, options, argument) We can't escape the analysis of , Let's face them .
commander: well , brother , Don't panic , There's me !
Yes , brother , it's wonderful to have you . Next we use commander This module parses the input parameters , The process and examples are as follows :
- Module installation
$ npm i commander
- src/index.js Example
......
import program from 'commander';
export function cli(args) {
program.parse(args);
}In a word , It's so crisp .
Daniel : Join in ? How to do? ?
In the next example , We will use these parsed input parameters . therefore , Please take a moment .
> Can't be without you : Version and help
Version and help information is a CLI The parts that must be provided , Otherwise, it would be unprofessional . Let's see how to achieve it .
modify src/index.js , The code is as follows :
import program from 'commander';
import pkg from '../package.json';
export function cli(args) {
program.version(pkg.version, '-V, --version').usage('<command> [options]');
program.parse(args);
} adopt program.version and usage The chain call is done , Still so cold .
Try to run the following command :
$ cook -V
$ cook -h
> Add generals : Add subcommand
Now we start to enrich CLI The function of , From add a subcommand start Start .
It has a parameter food and One option --fruit, The code is as follows :
......
export function cli(args) {
.....
program
.command('start <food>')
.option('-f, --fruit <name>', 'Fruit to be added')
.description('Start cooking food')
.action(function(food, option) {
console.log(`run start command`);
console.log(`argument: ${food}`);
console.log(`option: fruit = ${option.fruit}`);
});
program.parse(args);
} The above example shows how to get the parsed input parameters , stay action You can get everything you want , What do you want to do , It's entirely up to you .
Try running subcommands :
$ cook start pizza -f apple
> Seek foreign aid : Call external command
Sometimes , We need to be in CLI To call external commands , Such as npm And so on. .
execa: It's time for me to play .┏ (\^ω^)=*
- Module installation
$ npm i execa
- src/index.js Example
......
import execa from 'execa';
export function cli(args) {
.....
program
.command('npm-version')
.description('Display npm version')
.action(async function() {
const { stdout } = await execa('npm -v');
console.log('Npm version:', stdout);
});
program.parse(args);
} Passed above execa To call external commands npm -v. Come on , A print npm Version number of :
$ cook npm-version
> Promote communication : Provide human-computer interaction
Sometimes we want to CLI Be able to interact with users through question and answer , Users can provide the information we want by inputting or selecting .
At this point , A strong wind blew through , See only
Inquirer.jsCome running with colorful clouds .
- Module installation
$ npm i inquirer
The most common scenario is : Text input , Is it an option , check , The radio . Examples are as follows :
- src/index.js Example
......
import inquirer from 'inquirer';
export function cli(args) {
......
program
.command('ask')
.description('Ask some questions')
.action(async function(option) {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'What is your name?'
},
{
type: 'confirm',
name: 'isAdult',
message: 'Are you over 18 years old?'
},
{
type: 'checkbox',
name: 'favoriteFrameworks',
choices: ['Vue', 'React', 'Angular'],
message: 'What are you favorite frameworks?'
},
{
type: 'list',
name: 'favoriteLanguage',
choices: ['Chinese', 'English', 'Japanese'],
message: 'What is you favorite language?'
}
]);
console.log('your answers:', answers);
});
program.parse(args);
}The code is simple , Go straight to the renderings :
> Reduce anxiety : Wait for a reminder
Human computer interaction experience is very important , If you can't finish the work immediately , We need to timely feedback the progress of users' current work , This can reduce users' waiting anxiety .
oraandlistrShoulder to shoulder , Take a neat step , Come face to face .
The first thing to play is ora
- Module installation
$ npm i ora
- src/index.js Example
......
import ora from 'ora';
export function cli(args) {
......
program
.command('wait')
.description('Wait 5 secords')
.action(async function(option) {
const spinner = ora('Waiting 5 seconds').start();
let count = 5;
await new Promise(resolve => {
let interval = setInterval(() => {
if (count <= 0) {
clearInterval(interval);
spinner.stop();
resolve();
} else {
count--;
spinner.text = `Waiting ${count} seconds`;
}
}, 1000);
});
});
program.parse(args);
}Don't talk much , Directly above :
listr Then came .
- Module installation
$ npm i listr
- src/index.js Example
......
import Listr from 'listr';
export function cli(args) {
......
program
.command('steps')
.description('some steps')
.action(async function(option) {
const tasks = new Listr([
{
title: 'Run step 1',
task: () =>
new Promise(resolve => {
setTimeout(() => resolve('1 Done'), 1000);
})
},
{
title: 'Run step 2',
task: () =>
new Promise((resolve) => {
setTimeout(() => resolve('2 Done'), 1000);
})
},
{
title: 'Run step 3',
task: () =>
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('Oh, my god')), 1000);
})
}
]);
await tasks.run().catch(err => {
console.error(err);
});
});
program.parse(args);
}Still don't say much , Still directly above :
> Add some color : Let life be no longer monotonous
chalk: I am a young man of art , I live for art , It's up to me .<( ̄ˇ ̄)/
- Module installation
$ npm i chalk
- src/index.js Example
.....
import chalk from 'chalk';
export function cli(args) {
console.log(chalk.yellow('I like cooking'));
.....
}With color CLI, Does it make you feel more happy :
> Facade decoration : Add a border
boxen: This is my favorite , It's time to show me !<(ˉ^ˉ)>
- Module installation
$ npm i boxen
- src/index.js Example
......
import boxen from 'boxen';
export function cli(args) {
console.log(boxen(chalk.yellow('I like cooking'), { padding: 1 }));
......
} Um. , It looks more professional :
> Publish results : It can be published
If you are scope Way to publish , for example @daniel-dx/cook-cli. So in package.json Add the following configuration to make your release smooth ( Of course , If you are npm Paid members of , Then this configuration can be saved )
{
"publishConfig": {
"access": "public"
},
}finishing , launch :
$ npm publish
OK, Your... Has been released to the world CLI 了 , Now you can go to https://www.npmjs.com/ Go and find out what you published CLI 了 .
> Warm reminder : It's time to upgrade
update-notifier: It's finally me , I wait until the flowers are gone . X﹏X
- Module installation
$ npm i update-notifier
- src/index.js Example
......
import updateNotifier from 'update-notifier';
import pkg from '../package.json';
export function cli(args) {
checkVersion();
......
}
function checkVersion() {
const notifier = updateNotifier({ pkg, updateCheckInterval: 0 });
if (notifier.update) {
notifier.notify();
}
} For local debugging , We'll have local CLI Drop a version , hold package.json Of version It is amended as follows 0.0.9, And then run cook See the effect :
o( ̄︶ ̄)o perfect !
The development of an CLI Some necessary or common steps of .
Of course , If you just want to quickly develop one CLI, As some leaders often say : Don't tell me the process , I just want the result . It can be used as oclif These are designed for the development of CLI And the frame of life , Open the box .
And we as programmers , The context of the solution , Understanding of the past and the present , Still need to pay some time and energy for , This will make us more practical , go further .
Okay , I'll talk about it today , Goodbye to my friends !
Almost forgot , Attach the source code of the sample :https://github.com/daniel-dx/cook-cli
┏(^0^)┛ ByeBye!
Oh , Forget to say , My latest article will be published in the official account as soon as possible , If you are interested, please pay attention
边栏推荐
- Apple's legendary design team disbanded after jobs refused to obey cook
- Customize the toolbars of the kindeditor editor. Items removes unnecessary toolbars or retains some toolbars
- 进程与多线程
- 服乔布斯不服库克,苹果传奇设计团队解散内幕曝光
- Functions of document management what functions does the document management software have
- MYSQL_精讲数据库数据类型
- International Symposium on energy and environmental engineering in 2022 (coeee 2022)
- Quick completion guide for mechanical arm (zero): main contents and analysis methods of the guide
- [IEEE publication] 2022 International Conference on industrial automation, robotics and Control Engineering (iarce 2022)
- 初识string+简单用法(一)
猜你喜欢

Hill sorting graphic explanation + code implementation

Stack Title: exclusive time of function

机械臂速成小指南(零):指南主要内容及分析方法

【JS逆向分享】某个网站社区信息

Cool interactive animation JS special effects implemented by p5.js

Any 与 TypeVar,让 IDE 的自动补全更好用

服乔布斯不服库克,苹果传奇设计团队解散内幕曝光

Rising bubble canvas breaking animation JS special effect

A group of skeletons flying canvas animation JS special effect

初识string+简单用法(一)
随机推荐
23. opencv - image mosaic project
2022 International Symposium on intelligent robots and systems (isoirs 2022)
Fashionable pop-up mode login registration window
JMeter interface test tool foundation - badboy tool
Canvas pipe animation JS special effect
Stack Title: exclusive time of function
Petit guide de construction rapide du bras mécanique (II): application du bras mécanique
Differences among cookies, session, localstorage and sessionstorage
多线程的应用 - 提升效率
Besides technology, programmers also need to master a skill - self marketing ability
The latest entry date of SQL Sever test questions
How to use multiple kindeditor editors on a page and pass values to the server
[Qianfan 618 countdown!] IAAs operation and maintenance special preferential activities
Simple pricelist style code
Quick completion guide for mechanical arm (zero): main contents and analysis methods of the guide
Why should we make the best use of the external chain in SEO?
Detailed explanation of SQL Sever basic data types
Leetcode-223: rectangular area
解决DBeaver SQL Client 连接phoenix查询超时
283. move zero