Overview of basic tools
The purpose of scaffolding is to quickly build the basic structure of the project and provide a consistent specification for the team to code according to convention. At present, the commonly used scaffolding in daily work includes VUe-CLI, create-react-app, vite, etc. All of them complete the rapid construction of content through simple initialization commands. However, these only provide the most basic functions. This article will explain how to build a set of business scaffolding from the perspective of basic tools.
Before we look at scaffolding, let’s talk about some of the tool libraries we need to know when building a scaffold in actual production or reading the source code of other scaffolding:
Tool name | note |
---|---|
commander.js | The completenode.jsCommand line solution. |
chalk | Terminal styling |
Inquirer.js | A collection of commonly used interactive command-line user interfaces |
ora | The terminal controls the loading style |
download-git-repo | Download the remote template |
fs-extra | An extension of system FS |
ejs | Embedded javascript templates |
semver | NPM semantic version controller |
boxen | Create a box in the terminal |
Commander. Js command line command
Initialize a simple CLI project
{
"name": "@thrusterx/cli"."version": "0.0.1 - beta. 0"."description": "thrusterx frontend team"."main": "dist/scripts/bin/index.js"."author": "thrusterX"."license": "ISC"."bin": {
"t7x": "dist/scripts/bin/index.js"
},
"files": [
"dist"]."dependencies": {
"commander": "^ 8.3.0",}}Copy the code
Directory structure:
Thrusterx -cli ├─ exercises - ├─ bin │ ├─ ├─ download.jsonCopy the code
Introducing the commander
#! /usr/bin/env node
import { Command } from 'commander'
import pkg from '.. /.. /package.json'
const program = new Command()
program.name('t7x').usage('<command> [options]')
program.version(`@thrusterx/cli ${pkg.version}`).usage('<command> [options]')
program
.command('init <app-name>')
.description('init a new project')
.option('-d, --default'.'skip init project options')
.option('-c --all-config'.'create project with all config')
.option('-a, --all-plugins'.'create project with all plugins')
.option('-u, --uninstalled'.'skip install denpendencies')
.action((name: string, options: InitCliOptions) = > {
console.log('do something')
})
program.parse()
Copy the code
NPM link links to global
- Run the NPM link to apply @thrusterx/cli to the global link
- When finished, execute t7x on the command line
$ t7x -h
Usage: t7x <command> [options]
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
init [options] <app-name> init a new project
Copy the code
Beautify your console with Chalk
program
.command('init <app-name>')
.description('init a new project')
.option('-d, --default'.'skip init project options')
.option('-c --all-config'.'create project with all config')
.option('-a, --all-plugins'.'create project with all plugins')
.option('-u, --uninstalled'.'skip install denpendencies')
.action((name: string, options: InitCliOptions) = > {
/ / color
console.log('project name is ' + chalk.yellow(name))
console.log('project name is ' + chalk.green(name))
/ / the background color
console.log('project name is ' + chalk.bgBlue(name))
// Text style
console.log('project name is ' + chalk.bold(name))
// RGB color & hex
console.log('project name is ' + chalk.rgb(255.191.0).underline(name))
console.log('project name is ' + chalk.hex('#3C3C3C').bold(name))
console.log('project name is ' + chalk.bgHex('#FF0000').bold(name))
})
program.parse(process.argv)
Copy the code
Inquirer makes scaffolding more flexible
Inquirer makes your scaffolding more flexible with simple terminal interactions, official documentation
import { QuestionCollection } from 'inquirer'
export const promptList: Array<QuestionCollection> = [
{
type: 'input'.message: 'Version:'.name: 'version'.default: '0.0.1'}, {type: 'input'.message: 'Author:'.name: 'author'.default: 'thruster-x'}, {type: 'input'.message: 'Description:'.name: 'description'.default: 'thruster-x project'}, {type: 'list'.message: 'Please set the project template'.name: 'layoutTemp'.choices: ['baseLayout'.'emptyLayout'.'none'].filter: (val: string) = > {
return val
},
},
]
async function checkOptions() {
await inquirer
.prompt(promptList)
.then((answers: any) = > {
console.log(answers)
Object.assign(defaultOptions, answers)
})
.catch((error: any) = > {
return error
})
}
Copy the code
Ora command line loading active effect
Configure the policy template to download
Download templates from a remote repository via download-git-repo, refer to the create-vite repository, which provides templates for different projects, and write the configured parameters to the file via EJS
download('flippidippi/download-git-repo-fixture'.'test/tmp'.function (err) {
console.log(err ? 'Error' : 'Success')})const template: string = fs.readFileSync(filePath, 'utf-8')
const outputCode: string = ejs.compile(template, {})(config)
fs.writeFileSync(filePath, outputCode)
Copy the code
Child processes install dependencies
import { exec } from 'child_process'
exec(`cd ${config.name} && git init && npm install`.(err: any) = > {
console.log(err ? 'error' : 'success')})Copy the code
Scaffold version upgrade verification
Scaffolding versioning follows Semantic Versioning 2.0.0. When a new version of the repository is released, you execute the local scaffolding command and the console outputs an upgrade prompt
const nodeModules = resolve('.. /.. /.. /package.json')
const { latest, beta } = await getCliVersion()
fs.readFile(nodeModules, (err, data: any) = > {
if (semver.lt(version, latest)) {
console.log(boxen('xxxxxx'))}else{... }})Copy the code
When a new version becomes available:
When the beta is released: