I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!
Hello everyone, I am little Dudu, following the last 10 minutes, to build a proprietary CLI for you, we have completed the project download, install and run. (The new friends can take a quick look at it first.)
We have a situation in project development where pages are developed with the same module, like this
What other way to do repetitive things like imported files, fixed labels, components, etc. in seconds than copy and paste? At this time we can use cli, let him help us achieve faster
The final result
Let’s take a look at the final result:
Simply say is through the interaction, automatic file creation and route configuration of these two functions
tip
NPM link can be used locally without sending packets
project
Here I use my personal Ant-design-pro-V5 to explain (different projects, different configurations oh ~).
Create a file
Let’s start by thinking about the steps needed to create a file. First we need to define such a template to build quickly, and then copy the template to our own project.
So let’s create a file here, such as:
Then we’ll go through the folder and copy the file out with copyFile
const fileModule = resolve(__dirname, '.. /.. /module')
const files = fs.readdirSync(fileModule).filter((v) = >! [".git"].includes(v));
// Iterate over the required files to perform the copy
files.map(async (item) => {
const fromFileName = resolve(__dirname, `.. /.. /module/${item}`);
const toFileName = resolve(__dirname, `${desc}/${item}`);
fs.copyFile(fromFileName, toFileName, 0.() = >{})})Copy the code
So here we can optimize, we can check if the file that we’re creating has been created, and if it has, we can pop a box and say, this file is already created, do we want to delete it and reintroduce it, so let’s talk about how to delete the file
To delete a file, you need to delete all the subfiles in the file. To delete a directory file, use the fs.unlinkSync and fs.rmdirSync methods, along with some hints
// desc: file directory
const files = fs.readdirSync(desc)
files.map((item) = > {
fs.unlinkSync(`${desc}/${item}`)
})
fs.rmdirSync(desc)
Copy the code
Detailed code
create.ts:
const inquirer = require("inquirer");
const { resolve } = require("path");
const fs = require("fs");const { log } = require(".. /api");
const filePath = 'src/pages'
module.exports = async() = > {console.log("path", resolve("."));
create()
};
async function create(){
// Project name
const name = await inquirer.prompt([{
type: 'input'.message: 'Set file name 😎😎😎'.name: 'name',}])const desc = resolve(`. /${filePath}/${name.name}`);
log(desc)
// Check whether the file exists. If so, no message is displayed
const isFile = fs.existsSync(desc)
if(isFile){
deleteFile(desc)
return
}else{
await require(`./routes`)(name.name);
createFile(desc)
return}}async function createFile(desc){
try{
// Create a folder
fs.mkdirSync(desc)
const fileModule = resolve(__dirname, '.. /.. /module')
const files = fs.readdirSync(fileModule).filter((v) = >! [".git"].includes(v));
// Iterate over the required files to perform the copy
files.map(async (item) => {
const fromFileName = resolve(__dirname, `.. /.. /module/${item}`);
const toFileName = resolve(__dirname, `${desc}/${item}`);
fs.copyFile(fromFileName, toFileName, 0.() = >{})})}catch {
log('Creation failed'.'red')}}async function deleteFile(desc){
log(desc)
try{
// Whether to delete and re-establish
const answer = await inquirer.prompt([{
type: 'confirm'.name: 'confirm'.message: 'The current file already has this file, do you want to delete and then rebuild? '.default: false
}])
console.log("answer", answer);
if(answer.confirm){
// To delete modules, you need to delete files before deleting directories
const files = fs.readdirSync(desc)
files.map((item) = > {
fs.unlinkSync(`${desc}/${item}`)
})
fs.rmdirSync(desc)
await require(`./routes`)(answer.name);
createFile(desc)
}else{
create()
}
} catch {
log('Error occurred'.'red')}}Copy the code
Create routing
Let’s start with routing in V5:
As we can see, the general structure of the file is like this. In fact, it is not hard to find that we do not need to touch the route, so we can create a separate route module and then manually add it to the project
Effect:
We take the scaffolding to create a file for Routeschildren. ts where we need to note two points
- There is no
routesChildren.ts
Let’s just add it - There are
routesChildren.ts
So when we read this file, we need to read the file and splice it
Note: Fs. readFile and fs.writeFile require both strings, so HERE I intercept export default
Once we have created routesChildren.ts, we need to manually introduce routesChildren.ts into routes
async function create(nameFile){
const desc = resolve(`. /${filePath}`);
const isFile = fs.existsSync(desc)
const toFileName = resolve(__dirname, desc);
/ / write
const start = `export default`
if(isFile){
fs.readFile(toFileName, 'utf8'.async (err, data) => {
try{
const arr = JSON.parse(data.substring(14, data.length).trim())
const routerArr = await routerConfig(nameFile)
const res = [...arr, ...routerArr]
fs.writeFile(toFileName, `${start} The ${JSON.stringify(res)}`.(err) = > {
log('🚗🚗🚗 Route created successfully ')})}catch{
log('Wrong text format, please check format')}}}else{
const routerArr = await routerConfig(nameFile)
// If not
fs.writeFile(toFileName, `${start} The ${JSON.stringify(routerArr)}`.(err) = > {
log('🚗🚗🚗 Route created successfully ')}}}Copy the code
Detailed code
const inquirer = require("inquirer");
const { resolve } = require("path");
const fs = require("fs");const { log } = require(".. /api");
const filePath = 'config/routesChildren.ts'
module.exports = async (name) => {
console.log("path", resolve("."));
create(name)
};
async function create(nameFile){
const desc = resolve(`. /${filePath}`);
const isFile = fs.existsSync(desc)
const toFileName = resolve(__dirname, desc);
/ / write
const start = `export default`
if(isFile){
fs.readFile(toFileName, 'utf8'.async (err, data) => {
try{
const arr = JSON.parse(data.substring(14, data.length).trim())
const routerArr = await routerConfig(nameFile)
const res = [...arr, ...routerArr]
fs.writeFile(toFileName, `${start} The ${JSON.stringify(res)}`.(err) = > {
log('🚗🚗🚗 Route created successfully ')})}catch{
log('Wrong text format, please check format')}}}else{
const routerArr = await routerConfig(nameFile)
// If not
fs.writeFile(toFileName, `${start} The ${JSON.stringify(routerArr)}`.(err) = > {
log('🚗🚗🚗 Route created successfully ')}}}async function routerConfig(nameFile){
const name = await inquirer.prompt([{
type: 'input'.message: 'Please set route name'.name: 'name',}])console.log("answer", name.name);
const icon = await inquirer.prompt([{
type: 'input'.message: 'Please set icon name'.name: 'name'.default: 'FireOutlined'
}])
console.log("answer", icon.name);
return[{path: ` /${nameFile}`.name: name.name,
icon: icon.name,
component: `. /${nameFile}`,}}]Copy the code
Implementation effect
discuss
This chapter explains how to use the CLI to create a page. Of course, this function is not only to create a page, but also to create some common templates in a project. This method can be created in a few seconds.
Welcome everyone to leave a message for discussion, and attach the code address for everyone to visit, if it is helpful, give a small Star, support ~~
Git address: domesy- CLI
Other good posts:
- Create your own CLI in 10 minutes
- Build the React mobile framework out of the box
- Build your Own Ant Design Pro V5
- Some common Dom operations that can be easily obtained with a single Hook?