Yargs official address
In the past, every time to build a module, we had to manually create it, which was very tedious. After checking the company’s project, we found that Yargs was used for automatic creation, and we could customize commands and parameters to deal with problems. By learning YARgs, incidentally write an automatic module creation tool.
Step 1.
-
Step 1: Parameters to pass
There are three parameters
File: Folder and module name (required)
Path: indicates the file saving path
Type: indicates the template type
-
Step 2: Create a command and process the parameters passed in
command(cmd, desc, [builder], [handler])
Creates a command using the command method and puts the previously defined parameters into the command bulider.
[handler] Processes parameter transmission.
-
Step 3: Process parameters
1. Create a folder
2. Create a file
-
Step 4: Customize the template
It's not enough to be able to create a file, we need the file content to be the template content we defined, so we define the template first.
-
Step 5: Do some experience optimization, create file prompts, repeat file prompts
2. The directory
ReactTemplat and VueTemplate are user-defined templates that can be customized based on the template content and structure.
Cli.js: used to create commands and pass parameters to the start file for processing.
Start. js: handles parameters, creates folders and files, and interacts with the user using the process process.
Handle.js: method for handling files.
3. Help information
Node./tools/cli add -h // Display help information Options: --version Show version number [Boolean] -h Showhelp [boolean]
--file, -f create a file [required]
--path, -p file path [default: ""] - type, -t file 'stype [choices: "vue"."react"] [default: "vue"]
Examples:
node tools/cli add -p views -f test-t vue Creates one in the views directorytestThe templateCopy the code
Use 4.
node tools/cli add -f test -p views -t vue
Copy the code
Create a test module in the views directory. The module type is vue.
Check whether the directory exists when creating a module.
If duplicate modules are encountered, you can override them
Address of the file
cli.js
const argv = require('yargs')
.command(
'add'.'create a file'.function(yargs) {
return yargs
.option('file', {
alias: 'f',
describe: 'create a file'
})
.option('path', {
alias: 'p',
describe: 'file path',
default: ' '
})
.option('type', {
alias: 't',
describe: 'file' s type ',
choices: ['vue'.'react'], // Now there are two templates to choose from. You can design the template according to your own project situation.'vue'
})
.demandOption(['file'].'Please provide file to work with this tool')
.example(
'node tools/cli add -p views -f test -t vue'.'Create a test template in the views directory')},function(argv) {start(argv)}).help('h').argv
Copy the code
start.js
const handel = require('./handle')
const colors = require('colors')
const path = require('path')
module.exports = async function(argv) {
argv.file = argv.file.toString()
const existPathFolder = await handel.existFolder(path.resolve(argv.path))
const fileName =
argv.file.substring(0, 1).toUpperCase() + argv.file.substring(1)
let className = ' '
for (let i = 0; i < argv.file.length; i++) {
if (/[A-Z]/.test(argv.file[i])) {
className += The '-'
}
className += argv.file[i].toLowerCase()
}
if(argv.path ! = =' ') {
argv.path += '/'
}
const filePath = path.resolve(argv.path) + '/' + fileName
process.stdin.setEncoding('utf8')
const createFileData = {
filePath,
fileName,
className,
type: argv.type} // There is no path folderif(! ExistPathFolder) {console.warn(colors. Green (' whether to create${path.resolve(argv.path)}Folder? : y/n `)) process. Check stdin.'data', async chunk => {
chunk = chunk.replace(/[\s\n]/, ' ')
if (chunk === 'y') {// Create path folder await handel.createFolder(path.resolve(argv.path)) // Create component folder await handel.createFolder(filePath) // CreateFile await handel.createfile (createFileData) process.exit()}else if (chunk === 'n') {
process.exit()
} else {
console.warn(colors.red('Please enter the correct instruction: y/n'))
process.exit()
}
})
} else{// Check whether the component folder has const existFileFolder = await handel.existFolder(filePath)if (existFileFolder) {
console.warn(colors.green(`${fileName}The folder already exists. Do you want to overwrite it? : y/n `)) process. Check stdin.'data', async chunk => {
chunk = chunk.replace(/[\s\n]/, ' ')
if (chunk === 'y') {// create component folder await handel.createfolder (filePath) // createFile await handel.createfile (createFileData) process.exit()}else if (chunk === 'n') {
process.exit()
} else {
console.warn(colors.red('Please enter the correct instruction: y/n'))
process.exit()
}
})
} else{// create component folder await handel.createfolder (filePath) // createFile await handel.createfile (createFileData) process.exit()}}}Copy the code
handle.js
const fs = require('fs')
const colors = require('colors')
const path = require('path')
module.exports = {
existFolder: async function(path) {// Determine whether the argv.path folder existsreturn new Promise(function(resolve, reject) {
returnFs.exists (path, e => {resolve(e)})})}, /** * createFolder @param filePath filePath */ createFolder:function(filePath) {
return new Promise(function(resolve, reject) {
fs.mkdir(filePath, function(err) {
if (err) {
if (err.errno === -2) {
console.log(colors.red('Directory not found'))}else if (err.errno === -17) {
}
} else {
console.log(colors.green('Create folder:'))
console.log(colors.underline(`${filePath}'))} resolve()})})}, /** * @param args:{* filePath filePath * fileName fileName * className style name *typeFile type *} */ createFile:function({ filePath, fileName, className, type}) {const data = {fileName, filePath, className}type) {
case 'vue':
data.templateFolderPath = path.join(__dirname, './VueTemplate')
break
case 'react':
data.templateFolderPath = path.join(__dirname, './VueTemplate')
break
default:
data.templateFolderPath = path.join(__dirname, './VueTemplate')}returnnew Promise(async (resolve, reject) => { await this.readAndWiteFile(data, resolve) }) }, @param args:{* templateFolderPath template path * fileName fileName * filePath filePath * className style name *} * @param resolve */readAndWiteFile: function(
{ templateFolderPath, fileName, filePath, className },
resolve
) {
fs.readdir(templateFolderPath, 'utf8', (err, files) => {
if (err) {
console.log(colors.red(err))
return false
}
files.forEach(templateName => {
const FileName = templateName
.replace('TemplateName', fileName)
.replace('.txt'.' 'Create file fs.createWritestream ('${filePath}/${FileName}Const content = fs.readfilesync (') // 2${templateFolderPath}/${templateName}').tostring () // Reads the template file.replace(/\${TemplateName}/g, FileName.split('. ')[0])
.replace(/\${template-name}/g, className) // Replace templateName with the corresponding file name fs.writefilesync ('${filePath}/${FileName}`, content, 'utf8')
console.log(colors.green('Write file:'))
console.log(colors.underline(`${filePath}/${FileName}`))
})
resolve()
})
}
}
Copy the code
This method is cumbersome, and two versions are optimized below
1. You do not need to enter the handwritten path and type
(1) Node tools2/cli add -f fileName
(2) Prompt to select template
(3) Select the placement position to provide access to the next layer and return to the operation of the upper layer
2. You do not need to select paths layer by layer
Once the deep path appears above, the operation will be very tedious. Therefore, dynamic path selection is provided, and the path address is prompted according to the keyword.
steps
(1) Node tools3/ CLI
(2) Enter the file name
(3) Prompt to select template
(4) Prompt to place the address