With the continuous development of NodeJs, there are more things to do for the front end. A series of things such as Vue scaffolding, React scaffolding and so on stand out and enter people's vision. For these scaffolding tools, they just stay in the application stage, and never think about how scaffolding is realized. How the vue init webpack project name creates a project through such commands, the most important module of which is Commander today.
Commander module is compiled by TJ God abroad
Project address: Commander
Commander Basic Usage
Commander document is written in detail, follow the article to learn in detail, Commander is a Nodejs module, need to run in the Node environment, before using to confirm whether the Node environment has been installed.
Installation dependency
npm install commander --save
Options parsing
Under the Commander module, there exists an option method to define the options of the commander, which is used as the document for the options.
var program = require('commander'); program .option('-g, --git [type]', 'Add [marble]', 'Angie') .parse(process.argv); console.log("process.argv",process.argv) console.log("program.args",program.args) console.log('you ordered a pizza with:'); if (program.git) console.log(' - git'); console.log(' - %s git', program.git);
The above example parses args and options from process.argv, then assigns the remaining parameters (undefined parameters) to the args attribute (program.args) of the commander object, which is an array.
Print out process.argv and program.args and check the output as follows. Run the file using the following commands:
node index -g type Aaron
process.argv ['F:\\node\\installation\\node.exe', 'C:\\Users\\wo_99\\Desktop\\cli-dome\\index', '-g', 'type', 'Aaron' ] program.args [ 'Aaron' ]
The option method can receive three parameters:
- Custom logos must be divided into long and short logos, separated by commas, vertical lines or spaces, followed by necessary or optional parameters, the former containing with <> and the latter containing with [].
- Option Description Omits Error-free: Display Flag Description when Using the -- help command
- Default values can be omitted: default values are used when no parameters are passed in
If we execute node index -g, the result is Angie git whose third parameter is filled in the corresponding position as the default value. In addition to the above, you can use the following commands:
// Execution-g parameter a // Execution - b parameter s node index -g a -b s // Execute - g and - b to pass in a parameter to - g // - b parameter does not know how to pass in for the time being node index -gb a
Version options
The invoked version adds the - V and - version options to the command by default. When any of these options exists, the command prints the version number and exits.
var program = require('commander'); program .version('0.0.1') .parse(process.argv); // Execution of orders // node index -V // Output results // 0.0.1
If you want the program to respond to the - V option instead of the - V option, you just need to pass the custom flag to the version method using the same syntax as the option method. The version flag can be named any value, but long options are required.
var program = require('commander'); program .version('0.0.1', '-e, --version');
Command adds command name
This method allows the use of the command line to execute a command, that is, a section:
var program = require('commander'); program .version('0.0.1', '-V, --version') .command('rm <dir>') .action(function (dir, cmd) { console.log('remove ' + dir + (cmd.recursive ? ' recursively' : '')) }); program.parse(process.argv); // Execution of orders // node index rm /aaa -r // Output results // Remove / AAA recursivity: console content in code
The command function receives three parameters:
- The name of the command must be: the parameters contained in <> or [] can be followed by the command; the last parameter of the command can be variable, adding a flag after the array as in the example; the parameters passed after the command are passed into the callback function of action and the program.args array.
- Command description can be omitted: If there is an action(fn) call, the subcommand program will be started, otherwise an error will be reported.
- Configuration options can be omitted: configurable noHelp, isDefault, etc.
When the command is executed, the options of the command are validated, and any unknown option will report an error. However, options are not validated if action-based commands do not define actions.
var program = require('commander'); program .version('0.0.1', '-V, --version') .command('rm <dir>') .option('-r, --recursive', 'Remove recursively') .action(function (dir, cmd) { console.log('remove ' + dir + (cmd.recursive ? ' recursively' : '')) }); program.parse(process.argv); console.log(program.args) // Execution of orders // node index rm /aaa -r /ddd // Output results // remove /ddd recursively // [ '/aaa' ]
HelOption Help
Providing help information
var program = require('commander'); program .version('0.1.0') .helpOption('-h,--HELP') .option('-f, --foo', 'enable some foo') .option('-b, --bar', 'enable some bar') .option('-B, --baz', 'enable some baz'); program.parse(process.argv); // Execution of orders // node index -h or node index --HELP /* Output results * Options: * -V, --version output the version number * -f, --foo enable some foo * -b, --bar enable some bar * -B, --baz enable some baz * -h,--HELP output usage information */
Output help information and exit immediately. The optional callback cb allows post-processing of help text before it is displayed. HelOption also provides long names, - h, - - both are acceptable when HELP calls for long names after short names. The use of version is similar.
Description command description
The second parameter of command is also the description of command. When it coexists with description, it takes precedence over the description of the second parameter, and description is displayed at the top as a global description. This description can only be seen when - HELP is used.
var program = require('commander'); program .version('0.0.1', '-V, --version') .command('rm <dir>',"arg is description") .description("this is description") .option('-r, --recursive', 'Remove recursively') .action(function (dir, cmd) { console.log('remove ' + dir + (cmd.recursive ? ' recursively' : '')) }); program.parse(process.argv); // Execution of orders // node index -h // Output results /* this is description Options: -V, --version output the version number -r, --recursive Remove recursively -h, --help output usage information Commands: rm <dir> arg is description help [cmd] display help for [cmd] */
As can be seen from the output above, the final description of the rm command is arg is description, and if the second parameter is deleted, this is description will be output.
Custom Event Listener
Used to capture option s and command s, trigger functions when they are used by thieves.
var program = require('commander'); program .version('0.0.1', '-V, --version') .command('rm <dir>',"arg is description") .option('-r, --recursive', 'Remove recursively') .option('-g, --git [type]', 'Add [marble]', 'Angie') .option('-a, --am',"ampm") .action(() => { console.log(123) }); program.on('option:am', function () { console.log("on:am") }); program.on('option:recursive', function () { console.log("option:recursive") }); program.on('command:rm', function () { console.log("command:rm") }); program.on('option:git', function () { console.log("option:git") }); program.on('command:*', function () { console.log(987) console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' ')); process.exit(1); }); program.on('--help', function() { console.log('****************'); console.log('Examples:'); console.log('****************'); console.log(' $ deploy exec sequential'); console.log(' $ deploy exec async'); }); program.parse(process.argv);
Executing command and option separately triggers the corresponding function in turn, but when exactly did command:* trigger?
- command and option are defined but triggered when event capture is not performed
- When a parameter is specified or there is no parameter, the function is triggered by an incoming parameter.
- No command
The above triggers the command:* corresponding event, option: closely followed by the long name of option. Only then can the event be captured.
Developing Local Modules
Create project files as follows:
├─bin │ └─init-project.js ├─lib │ └─install.js └─templates └─dome1
After creating the project directory, install the following dependency packages:
- chalk
- commander
- fs-extra
- path
- through2
- vinyl-fs
- which
Command: npm install --save-dev chalk commander fs-extra through2 vinyl-fs which path
First, add #!/usr/bin/env node in the first line of init-project.js, which is used to specify the executor of the script, where Node can be used!/usr/bin/node, if the user installs Node in a non-default path, Node will not be found. So ~ It's better to select env environment variables to find the Node installation directory.
init-project.js
#! /usr/bin/env node // Introducing dependencies var program = require('commander'); var vfs = require('vinyl-fs'); var through = require('through2'); const chalk = require('chalk'); const fs = require('fs-extra'); const path = require('path'); // Define version number and command options program .version('1.0.0') .option('-i --init [name]', 'init a project', 'myFirstProject') program.parse(process.argv); if (program.init) { // Get the project root directory to be built var projectPath = path.resolve(program.init); // Get the name of the project to be built var projectName = path.basename(projectPath); console.log(`Start to init a project in ${chalk.green(projectPath)}`); // Create folders based on the project name to be built fs.ensureDirSync(projectName); // Get the demo1 directory under the local module var cwd = path.join(__dirname, '../templates/demo1'); // Read and remove all files from the node_modules directory from the demo1 directory and filter them vfs.src(['**/*', '!node_modules/**/*'], { cwd: cwd, dot: true }). pipe(through.obj(function (file, enc, callback) { if (!file.stat.isFile()) { return callback(); } this.push(file); return callback(); })) // Write the stream of files read from the demo1 directory to the folder you created earlier .pipe(vfs.dest(projectPath)) .on('end', function () { console.log('Installing packages...') // Change the node working directory to the project root directory under construction process.chdir(projectPath); // Execute installation commands require('../lib/install'); }) .resume(); }
install.js
// Introducing dependencies var which = require('which'); const chalk = require('chalk'); var childProcess = require('child_process'); // Open subprocesses to execute npm install commands function runCmd(cmd, args, fn) { args = args || []; var runner = childProcess.spawn(cmd, args, { stdio: 'inherit' }); runner.on('close', function (code) { if (fn) { fn(code); } }) } // Find commands for installing dependency packages in the system function findNpm() { var npms = ['tnpm', 'cnpm', 'npm']; for (var i = 0; i < npms.length; i++) { try { // Find the first instance of the executable specified under the environment variable which.sync(npms[i]); console.log('use npm: ' + npms[i]); return npms[i] } catch (e) { } } throw new Error(chalk.red('please install npm')); } var npm = findNpm(); runCmd(which.sync(npm), ['install'], function () { console.log(npm + ' install end'); })
After completing the above code, change package.json to add the following attributes:
{ "bin": { "q-init": "./bin/init-project.js" } }
Note: The file specified after the custom instruction must be added. js suffix file name, otherwise an error will be thrown.
Next is the test. For testing, there is no need to push the installation package into npm. NPM provides npm link command for convenience, which can realize pre-release. If there are no errors in using npm link in the project root directory, the push is successful. Now you can use q-init globally.
Using initP-h command globally, the ability to output compiled help information indicates that the project can be initialized.
Usage: init-project [options] Options: -V, --version output the version number -i --init [name] init a project (default: "myFirstProject") -h, --help output usage information
summary
commander plays a very important role in Vue-cli and creat-app(react). This way of creating scaffolding is different from that of vue-cli. vue-cli uses git to remotely pull the project and then complete initialization. This way, it is more convenient and flexible. Each template change does not need to upload the package again, but only needs to change G. It warehouse is good, convenient and fast.
git address: cli-dome