This article is based on the requirements of our company to write a simple scaffolding tool.

First of all, let’s analyze the requirements: at present, the company has many projects, which belong to different customers. Each project is independently deployed, but the front-end framework of the project is basically divided into three types:

  • Embedded H5 page with APP as carrier: VUE family bucket + Vant UI
  • Admin background management system: Vue family bucket + Element UI
  • Admin Background management system: React + Ant Design

This article does not cover the implementation of a specific front-end project framework, but only the use of scaffolding tools to generate simple project templates when creating projects according to the needs of the business.

Create a project

mkdir gt-cli
cd gt-cli
npm init
Copy the code

package.json

{" name ":" gt - cli ", "version" : "1.0.0", "description" : ""," scripts ": {" test", "echo \" Error: no test specified\" && exit 1" }, "bin": { "gt": "bin/gt.js" }, "url": "", "email": "", "author": "Iris Mei", "repository": { "type": "git", "url": "" }, "license": "ISC", "dependencies": { "chalk": "^ 4.1.0" and "commander", "^ 7.0.0", "the inquirer" : "^ 7.3.3", "log - symbols" : "^ 4.0.0"}}Copy the code

Install dependencies

npm install
Copy the code

Chalk: handles the style (color, background color) of the command line output text

Commander: Node command line solution

Inquirer: Node command line interaction (information entry, selection, confirmation, etc……)

Log-symbols: prints log ICONS, such as √, ×

The directory structure

┌ ─ ─ ─ gt – cli

│├─ Bin folder

│ ├ ─ gt. Js

│├─ Command folder

│ ├ ─ init. Js

│├─ Node_module folder

│ ├ ─ ─ gitignore

│ ├ ─ ─ package. Json

│ ├ ─ ─ the README, md

│ ├ ─ ─ the template. The json

Gt. js: entry file

Init.js: Initializes the project logic code

Template. json: Descriptions of different project templates and Git repository addresses

Start coding

First, configure the name, description, and warehouse address of the different project templates in template.json:

{"vue-admin": {"gitUrl": "git repository address ", "name": "admin system(vue + element)"}, "vue-web": {"vue-admin": {"gitUrl": "git repository address ", "name": "admin system(vue + element)"}, "vue-web": {"gitUrl": "Git repository address ", "name": "web H5 (vue + vint)"}, "react-admin": {"gitUrl": "git repository address ", "name": "admin system(react + ant design)" } }Copy the code

In gt.js, different actions are performed for different commands. Besides viewing the version number and using help, now only initializes the project, using GT init to initialize the project template.

#! /usr/bin/env node --harmony 'use strict' // terminal icon const symbols = require('log-symbols') // terminal command line beautify const chalk = Require ('chalk') // node command line solution const program = require('commander') // cli version program.version (require('.. /package.json').version) // Program.usage ('<command>') // Initialize a project command: Gt init < projectName > | | gt I < projectName > program. The command (' init ') / / command. The description (' init a new project ') / / description .alias(' I ') // Command alias.action (() => { If (program.args. Length < 2) {console.log(symbol. error, chalk. Red ('Please input the project name, for example: gt init vue-app')) process.exit() } require('.. /command/init')(program.args[1])}) // Handle illegal commands program.arguments ('<command>').action(CMD => {// Output help messages console.log(symbols.error, chalk.bgRed(`Unknown command: ${cmd}.`)); program.help() }); Parse (process.argv) // If there are no arguments on the command line, run help! program.args.length && program.help()Copy the code

Init.js handles the logic of initializing the project: the user enters the project information, selects the template, scaffolding pulls the project template from the Git repository, and installs the dependencies. Complete code:

// Execute complex command line commands const exec = require('child_process'). Exec // terminal icon const symbols = require('log-symbols') // Const inquirer = require('inquirer') // Terminal command line beautify const chalk = require('chalk') // template type const projectTpl = require('.. /template.json') module.exports = async (name) => {// Exports = async (name) const promptList = [{type: 'input', message: `project name(default: ${name}): `, name: 'projectName', default: name }, { type: 'input', message: `The project description: `, name: 'description', }, { type: 'list', message: 'please choose a project template: ', name: 'projectType', choices: Object.keys(projectTpl), filter: function (val) { return projectTpl[val]; } }]; Let answers = await inquirer. Prompt (promptList) // Confirm item information let confirm = await inquirer. Prompt ([{type: 'confirm', message: `Please confirm the project infomation: \n project name: ${answers.projectName} \n project description: ${answers.description} \n project template: ${answers.projecttype. name} \n are you sure? ', name: 'isSure', default: '}]) Confirm. IsSure) {console.log(chalk. BgYellow ('The process already exited.')) process.exit()} // Pull The project template, Using The master branch const CMD = ` git clone ${answers. ProjectType. GitUrl} ${answers. The projectName} ` / / initialization program The console. The log (' The project start cloning...... ') exec(cmd, (error) => { if (error) { console.log(symbols.error, chalk.red(error)) process.exit() } console.log(symbols.success, chalk.green('git clone is successed! ')) console.log('\n npm install...... ') exec(`cd ${answers.projectName} && npm install`, (error) => { if (error) { console.log(symbols.error, chalk.red(error)) console.log(symbols.error, chalk.red(`please npm install again or use cnpm install`)) process.exit() } console.log(symbols.success, chalk.green('Generation completed! ')) process.exit() }) })}Copy the code

Local debugging

Execute the NPM link in the package.json sibling directory to create a link to the local NPM module.

If the following information is displayed, the link is successful:

Audited 39 Packages in 1.408s 6 Packages are looking for funding run 'NPM fund' for details found 0 December \Users\ Your User Name \AppData\Roaming\ NPM \gt -> C:\Users\ Your User name \AppData\Roaming\ NPM \node_modules\gt-cli\bin\gt.jsC:\Users\ Your User name \AppData\ NPM \node_modules\gt-cli -> C:\Users\ your username \Desktop\workspace\gt-cliCopy the code

Now you can try to create an empty project template using your own scaffolding, in the terminal: gt init < project name >

Then enter the project information as prompted:

? project name(default: demo): (demo) ? The project description: A test project ? please choose a project template: (Use arrow keys) > vue-admin vue-web react-admin ? Please confirm the project infomation: project name: demo project description: A test project project template: admin system(vue + vue router + vuex) are you sure? (Y/n) Yes The project start cloning...... Git clone is successed! npm install...... C:\Users\iris.mei\Desktop\test process. CWD √ Generation completed!Copy the code

To cancel link, run NPM unlink < module name > in C:\Users\ Your Username \AppData\ NPM \node_modules:

Write in the last

A simple scaffold is written, and there are many points that can be optimized:

  • Methods encapsulate
  • Project Catalog validation
  • Directory Name Verification
  • .

I first throw a brick, later free to optimize again ~~

Finally, part of the code borrowed from other big blogs, learn from big ~~

If the article is not appropriate, welcome to correct ~~