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
#! /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 ~~