preface
The scaffolding tool vue has vue-cli and react has create-react-app, which generates new project templates based on options. But often these customized enough, after generating project will need to add a lot of configuration, from the generation, there is still a gap, which can be treated by customizing their own cli tool, do a simple cli tools, integrated their default template, according to the template to generate, follow-up can add and update the maintenance of the template.
package.json
As a CLI tool, you need to be able to execute commands on the command line, so you need to declare in package.json. The main field is bin, and the executable file is declared as follows: GDPG is an executable command, and SRC /index.js is executed
"bin": {
"gdpg": "src/index.js"
},
Copy the code
Executable file
SRC /index.js to indicate an executable file
#! /usr/bin/env node
Copy the code
This section describes cli related tool libraries
commander
The main function of commander is to take parameters on the command line, for example
gdpg init -l
# or
gdpg init --local
Copy the code
The code is as follows: GDPG -v or GDPG –version will print the current VERSION of the CLI. Add parameters can be defined by the accepted parameters to achieve the corresponding function
program
.version(pkg.version, '-v, --version')
.usage('<command> [options]')
.description('Standard tooling generate dir from templates')
program
.command('init [name]')
.description('Create a project')
.option('-l, --local'.'Create dir from local template')
.option('-g, --git'.'Create dir from git address')
.action((name, options) = > {
console.log(name, options.local, options.git)
})
Copy the code
inquirer
Inquirer: input, number, confirm, yes, no, list, rawlist, expand, checkbox, password, password Editor launches an instance of the user’s preferred editor on a temporary file.
type: (String) Type of the prompt. Defaults: input – Possible values: input, number, confirm, list, rawlist, expand, checkbox, password, editor
Ask the user’s choice, perform different operations according to the user’s choice, generate different templates
ora
Equivalent to the progress bar in the command line terminal, used to indicate the start and end of the action, load medium state
chalk
Chalk, or chalk, outputs colored text in a command line terminal
download-git-repo
Download and extract a Git repository (GitHub, GitLab, Bitbucket) from a node
update-notifier
Update notification procedures, toolkits have updated words prompt
const updateNotifier = require('update-notifier');
const pkg = require('./package.json');
updateNotifier({pkg}).notify();
Copy the code
GDPG – CLI function example
Several recent initialization default templates are available. Eslint, prettier, Husky, CommitLint, Vue -router/react-router-dom, Axios, and many more are already preset
The directory structure
GDPG - cli ├ ─ ─ LICENSE ├ ─ ─ the README. Md ├ ─ ─ dir. Md ├ ─ ─ example. The PNG ├ ─ ─ generators │ ├ ─ ─ react17 │ ├ ─ ─ vue2 │ ├ ─ ─ vue3 │ ├ ─ ─ │ ├─ ├─ ├─ download.txt │ ├─ download.txt │ ├─ download.txt │ ├─ download.txt │ ├─ download.txt │ ├─ download.txt │ ├─ download.txtCopy the code
package.json
{
"name": "gdpg-cli"."version": "1.0.0"."license": "MIT"."main": "lib/index.js"."bin": {
"gpdg": "lib/index.js"
},
"files": [
"lib"]."dependencies": {
"chalk": "^ 4.4.1"."commander": "^ 7.2.0"."download-git-repo": "^ 3.0.2." "."fs-extra": "^ 10.0.0"."inquirer": "^ 7.3.3." "."log-symbols": "^ 2.2.0." "."ora": "^ 5.4.0"."update-notifier": "^ 5.1.0"
},
"scripts": {
"lint": "eslint --fix"."prettier": "prettier --write lib"."release": "standard-version"
},
"devDependencies": {
"@commitlint/cli": "^ 12.1.1." "."@commitlint/config-conventional": "^ 12.1.1." "."eslint": "^ 7.26.0"."eslint-config-prettier": "^ 8.3.0"."eslint-plugin-prettier": "^ 3.4.0"."husky": "^ 4.3.7"."lint-staged": "^ 10.5.3"."prettier": "^ 2.3.0." "."standard-version": "^ 9.3.0"
},
"engines": {
"node": "> = 10.12"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"."commit-msg": "commitlint -e $HUSKY_GIT_PARAMS"}},"commitlint": {
"extends": [
"@commitlint/config-conventional"]},"lint-staged": {
"*.{js}": [
"prettier --write"."eslint --fix"."git add"]}}Copy the code
lib/generator.js
const inquirer = require('inquirer')
const fsExtra = require('fs-extra')
const download = require('download-git-repo')
const ora = require('ora')
const log = require('./log')
// const path = require('path')
/** * Three options: 1. Default 2. Download from git 3. Clone * gdpgGenerator select templates from presets * gitGenerator downloads templates from Git * localGenerator downloads templates from local */
/ * * *@param {*} Prompt query option *@param {*} Action Executes the function */ after the query
const generator = (prompt, action) = > {
inquirer
.prompt(prompt)
.then((answers) = > {
action(answers)
})
.catch((error) = > {
if (error.isTtyError) {
log.error(`Prompt couldn't be rendered in the current environment`)}else {
log.error(error)
}
})
}
const spinner = ora('Download from template... ')
const successInfo = (name) = > {
spinner.succeed()
console.log(
` ▄ █ █ █ █ ▓ █ █ █ █ █ ▄ █ █ ▓ █ █ █ ▄ █ █ █ █ ▄ █ █ █ █ ▄ █ █ ▓ █ █ ▓ █ █ ▒ ▀ █ ▒ ▒ █ █ ▀ █ █ ▌ ▓ █ █ ░ █ █ ▒ █ █ ▒ ▀ █ ▒ ▒ █ █ ▀ ▀ █ ▓ █ █ ▒ ▓ █ █ ▒ ▒ █ █ ░ ▄ ▄ ▄ ░ ░ █ █ █ ▌ ▓ █ █ ░ █ █ ▓ ▒ ▒ █ █ ░ ▄ ▄ ▄ ░ ▒ ▓ █ ▄ ▒ █ █ ░ ▒ █ █ ▒ ░ ▓ █ █ █ ▓ ░ ▓ █ ▄ ▌ ▒ █ █ ▄ █ ▓ ▒ ▒ ░ ▓ █ █ █ ▓ ▒ ▓ ▓ ▄ ▄ █ █ ▒ ▒ █ █ ░ ░ █ █ ░ ░ ▒ ▓ █ █ █ ▀ ▒ ░ ▒ █ █ █ █ ▓ ▒ █ █ ▒ ░ ░ ░ ▒ ▓ █ █ █ ▀ ▒ ▒ ▓ █ █ █ ▀ ░ ░ █ █ █ █ █ █ ▒ ░ █ █ ░ ░ ▒ ▒ ▒ ▒ ▓ ▒ ▒ ▓ ▒ ░ ░ ░ ░ ▒ ▒ ░ ░ ▒ ▒ ░ ░ ▒ ░ ▓ ░ ░ ▓ ░ ░ ░ ▒ ▒ ░ ▒ ░ ░ ░ ░ ▒ ░ ░ ▒ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ I did not do that myself
)
log.success(` 🎉 Successfully created the project${name}. `)
log.success('👉 Get started with the following commands:\n')
log.bash(`cd ${name}`)
log.bash(`yarn install`)}const GDPG_PROMPTS = [{
name: 'version'.message: 'Select version'.type: 'list'.choices: [{
name: 'Vue 2 + Javascript + Less'.value: 'vue2'
},
{
name: 'Vue 3 + Javascript + Less'.value: 'vue3'
},
{
name: 'Vue 3 + Typescript + Sass + ElementPlus'.value: 'vue3_ts'
},
{
name: 'Vue 3 + Typescript + Sass + ElementPlus + Vite'.value: 'vue3_vite'
},
{
name: 'React 17 + Javascript + Less + Antd'.value: 'react17'}}]]const downLoadUrl = 'direct:https://github.com/xxx/gdpg-cli/archive/refs/heads/master.zip'
const downLoadFromZip = (dir, name) = > {
download(downLoadUrl, name, {
map: file= > {
file.path = file.path.replace(`generators/${dir}/ `.' ')
return file;
},
filter: file= > {
return file.path.indexOf(`generators/${dir}/ `) > -1}},(err) = > {
if (err) {
spinner.fail()
log.error(err)
} else {
successInfo(name)
}
})
}
const gdpgGenerator = (name) = > {
generator(GDPG_PROMPTS, (answers) = > {
spinner.start()
downLoadFromZip(answers.version, name)
})
}
const GIT_PROMPTS = [{
name: 'version'.message: 'Enter git address'.type: 'input'.name: 'git'
}]
const gitGenerator = (name) = > {
generator(GIT_PROMPTS, (answers) = > {
spinner.start()
download(`direct:${answers.git.trim()}`, name, {
clone: true
}, (err) = > {
if (err) {
spinner.fail()
log.error(err)
} else {
successInfo(name)
}
})
})
}
const LOCAL_PROMPTS = [{
name: 'version'.message: 'Enter local address'.type: 'input'.name: 'path'
}]
const localGenerator = (name) = > {
generator(LOCAL_PROMPTS, (answers) = > {
spinner.start()
fsExtra.copy(answers.path.trim(), `. /${name}`.(err) = > {
if (err) {
spinner.fail()
log.error(err)
return
}
successInfo(name)
})
})
}
module.exports = {
gdpgGenerator,
gitGenerator,
localGenerator
}
Copy the code
lib/index.js
#! /usr/bin/env node
const program = require('commander')
const pkg = require('.. /package.json')
const updateNotifier = require('update-notifier')
const log = require('./log')
const fs = require('fs')
updateNotifier({ pkg }).notify({ isGlobal: true })
const { gdpgGenerator, gitGenerator, localGenerator } = require('./generator')
/** * program asks for help. If no arguments are entered, the help view command */ is output
program
.version(pkg.version, '-v, --version')
.usage('<command> [options]')
.description('Standard tooling generate dir from templates')
program
.command('init [name]')
.description('Create a project')
.option('-l, --local'.'Create dir from local template')
.option('-g, --git'.'Create dir from git address')
.action((name, options) = > {
if(! name)return log.error('Please input your project name')
// Check whether the local directory already exists
if (fs.existsSync(name)) return log.error('Project name already exist')
if (options.git) {
gitGenerator(name)
} else if (options.local) {
localGenerator(name)
} else {
gdpgGenerator(name)
}
})
program.parse(process.argv)
const commandName = program.args.length
if(! commandName) { program.help() }Copy the code
lib/log.js
const chalk = require('chalk')
const logSymbols = require('log-symbols')
module.exports = {
success: (text) = > console.log(logSymbols.success, chalk.green(text)),
info: (text) = > console.log(logSymbols.info, chalk.blue(text)),
bash: (text) = > console.log(chalk.cyan(` $${text}`)),
warning: (text) = > console.log(logSymbols.warning, chalk.yellow(text)),
error: (text) = > console.log(logSymbols.error, chalk.red(text))
}
Copy the code
The installation
npm i -g gdpg-cli
# or
yarn global add gdpg-cli
Copy the code
Check the version
gdpg -v
# or
gdpg --version
Copy the code
See the help
gdpg -h
# or
gdpg --help
Copy the code
1. Pull the build project from the default template
gdpg init <project-name>
Copy the code
2. Download the template from Git to build the project
gdpg init -g <project-name>
# or
gdpg init --git <project-name>
Copy the code
3. Download the generated project from the local folder
gdpg init -l <project-name>
# or
gdpg init --local <project-name>
Copy the code