node custom command line tool cli

Posted by camoconnell.com on Sat, 15 Jan 2022 05:51:20 +0100

Objective: to create a cli tool called sun

Create project folder

mkdir vue-auto-router-cli

Initialize package json

npm init -y

Installation dependency

npm i commander download-git-repo ora handlebars figlet clear chalk open watch -s

npm package nameeffect
commanderFor custom commands
download-git-repoFor downloading github projects
oraUsed to display loading
handlebars
figletYou can output posters similar to logo on the command line for printing welcome pages. It is an asynchronous process
clearClean command line interface
chalkModify the color of characters entered on the command line
open
watch

Initial experience of custom commands

Create / bin / sun JS file

#!/usr/bin/env node
// The previous line of code specifies that the code interpretation environment is node
console.log("cli");

package.json configuration executable command

  "bin": {
    "sun": "./bin/sun.js"
  },

In this way, a command sun is built. Before using it in the local environment, it is necessary to soft connect the npm link, which is equivalent to the global installation of the whole sun plug-in, and then it can be used like other command-line tools

sun
// After the sun command is executed, / bin / sun Code in JS

Customize the command sun init < name > to generate the project template locally

Objective: this step is mainly to customize a command sun init < name > with the help of the commander library. After entering the command, output the welcome interface and download a vue project template from githuh to the local

Output welcome interface

  • Modify / bin / sun JS, custom command sun init < name \ >
#!/usr/bin/env node
// The previous line of code specifies the interpretation environment
const program = require("commander");
program.version(require("../package.json").version);

// Define a new command sun init xxx
program
  .command("init <name>")
  .description("init project")
  .action((name) => {
    // Contents of the current command execution
    console.log("init" + name);
  });
// Process indicates the current main process
// argv indicates the parameters carried by the current command
program.parse(process.argv);

At this time, execute the command sun, and the currently executable commands will be displayed. The effect is as follows

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-uap6n9fd-1627110719518) (/ users / xiongweiliu / library / Application Support / typora user images / image-20210721211446501. PNG)]

  • Customize the execution content of the command sun init < name >, and output the welcome interface

New file / lib / init js

// node's own tool library util
// Promise can wrap ordinary methods in promise style
const { promisify } = require("util");

// figlet can output posters similar to logo on the command line for printing welcome pages. It is an asynchronous process
const figlet = promisify(require("figlet"));
// Clear screen
const clear = require("clear");
// chalk can modify the character color of command line output
const chalk = require("chalk");

const log = (content) => console.log(chalk.green(content));

module.exports = async (name) => {
  clear();
  const welcomeContent = await figlet(`SUN Welcome`);
  log(welcomeContent);
};

Modify / bin / sun The command sun init < name > defined in JS modifies the execution content of the command to

program
  .command("init <name>")
  .description("init project")
  .action(require("../lib/init"));

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-xbu6n83n-1627110719521) (/ users / xiongweiliu / library / Application Support / typora user images / image-20210721220445086. PNG)]

Download project template

Create a new / lib / download js

This step mainly involves the following knowledge points:

  • The download git repo library downloads project templates from github

  • ora shows the effect of waiting for downloading

const { promisify } = require("util");

module.exports.clone = async function (repo, dest) {
  const download = promisify(require("download-git-repo"));
  // Displaying loading during downloading project template
  const ora = require("ora");
  const process = ora(`download ing......${repo}`);
  process.start();
  await download(repo, dest);
  process.succeed();
};

Modify / lib / init. Again JS content, import template download code

module.exports = async (name) => {
  clear();
  const welcomeContent = await figlet(`SUN Welcome`);
  log(welcomeContent);

  // Download project template
  const { clone } = require("./download");
  // Use the download git repo library to download the project, and the address needs to be modified
  // If the download is http://github.com/su37josephxia/vue-sample , change to GitHub: su37josephxia / Vue sample
  const repoName = "github:su37josephxia/vue-sample";
  log("Create project:");
  clone(repoName, name);
};

Install project dependencies

An available command has been built in the first two steps. A project template has been created locally by running sun init < name >. In order to have a better experience, you can not only create a project template, but also automatically install the dependencies of the template

This step mainly involves the following knowledge points

  • Child process_ The spawn method of process starts the subprocess and downloads the dependencies.

    reference resources https://blog.csdn.net/chy555chy/article/details/52556318

    How to use spawn: http://nodejs.cn/api/child_process.html#child_process_child_process_spawn_command_args_options

  • Import the dependencies downloaded by the sub process into the main process project through the Stream

At / lib / init JS defines the method to open the child process

// node's own tool library util
// Promise can wrap ordinary methods in promise style
const { promisify } = require("util");

// figlet can output posters similar to logo on the command line for printing welcome pages. It is an asynchronous process
const figlet = promisify(require("figlet"));
// Clear screen
const clear = require("clear");
// chalk can modify the character color of command line output
const chalk = require("chalk");
// Project template
const { clone } = require("./download");

const log = (content) => console.log(chalk.green(content));

// Open child process
const spawn = async (...args) => {
  const { spawn } = require("child_process");
  return new Promise((resolve) => {
    const proc = spawn(...args);
    // The subprocess started by spwan returns the stream objects of two standard outputs stdout and stderr
    // Import the flow object of the child process into the main process process through pipe
    proc.stdout.pipe(process.stdout);
    proc.stderr.pipe(process.stderr);

    proc.on("close", () => {
      resolve();
    });
  });
};

module.exports = async (name) => {
  clear();
  const welcomeContent = await figlet(`SUN Welcome`);
  log(welcomeContent);

  // Download project template
  // Use the download git repo library to download the project, and the address needs to be modified
  // If the download is http://github.com/su37josephxia/vue-template , change to GitHub: su37josephxia / Vue template
  const repoName = "github:su37josephxia/vue-template";
  log("Create project:");
  clone(repoName, name);

  // Installation dependency
  log("Installation dependency");
  await spawn("cnpm", ["install"], { cwd: `./${name}` });
  log(`
  👌installation is complete
  To get Start:
  =================
  cd ${name}
  npm run serve
  =================
  `);
};

Autorun project

After the dependency is installed, it can be further optimized with the help of sub processes, automatically run the project, and open the project in the browser

  • spawn open subprocess run project
  • Open library open browser
	const open = require('open')
  // Run the project and open the browser
  await spawn("npm", ["run", "serve"], { cwd: `./${name}` });
  open("http://192.168.3.5:8080/");

Topics: node.js cli