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 name | effect |
---|---|
commander | For custom commands |
download-git-repo | For downloading github projects |
ora | Used to display loading |
handlebars | |
figlet | You can output posters similar to logo on the command line for printing welcome pages. It is an asynchronous process |
clear | Clean command line interface |
chalk | Modify 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/");