01 preface
It’s just that you’re in front-end development and programmers of all levels have used vue or React scaffolding. In today’s post, let’s build our own scaffolding from scratch.
What is a scaffold for?
In the case of VUE, every time we initialize a project using scaffolding, there is already a lot of code in it. This is the standard project that scaffolding initializes for us. In other words, scaffolding does repetitive, standardized things for us.
Why do we build our own scaffolding when we already have the official one?
1. Scaffolding will customize a standardized project for us, so we may have our own customization requirements in the actual business line. If it’s ok to occasionally customize a project, if the company adopts the standard for several projects, then the customized standard project can be understood internally as standardization. Since it is standardized, it is necessary to make a standard (scaffolding). 2. Study. The best way to know your enemy is to join him. The best way to learn how to use a technology is to implement it.
Don’t say more, do it!!
02 Function Description
Know yourself and know your enemy, and you can win a hundred battles. We realize a scaffold, first to know what he can have what functions, to try to do these functions:
1. Identify the console input
2. Console interaction
3. Download our template project
Identify the console input
Similar to what we typed –help on the console, the console needs to understand what we typed
Console interaction
When we create a project using vue Create Name, we are given the choice between default creation and configuration creation. If you choose to create a configuration version, you will also be given the option to configure vuex, VUE-Router, ESLint, etc.
Download our template project
When we finish the selection, we will download, download failure judgment, disconnection operation and so on.
03 Project Structure
Create a directory cuteXuan-cli
NPM init -y create bin, lib folders
Create file Xuan in bin and write the following information
#! /usr/bin/env node
console.log("hello cuteXuan-cli")
Copy the code
At this point we can modify our package.json file by adding the bin property to it
"Name" : "cuteXuan - cli", "version" : "1.0.0", "description" : ""," main ":" index. Js ", "bin" : {" cuteXuan - cli ": "./bin/xuan", "xuan": "./bin/xuan" },Copy the code
At this point our basic structure is set up, and it’s time to perform the most important step: open our console, or terminal. Execute the following command
NPM link --force NPM link --force if you have done this beforeCopy the code
If your console is anything like mine, congratulations, you’ve made the most important step. We have put our own package (scaffolding) into the global NPM. That is, at this point, you can manipulate its commands globally, just as you can with the Vue and React scaffolding. Note: The command is the bin property we configured in the package.json file. CuteXuan – CLI and Xuan are available.
If you make it this far, congratulations, your scaffolding is half done.
04 Use Commander to resolve input parameters
npm i commander
Copy the code
We usually use vue create XXX
Vue –version vue –help commands. If you want to perform further operations, you need to parse the user’s input parameters. Of course, abbreviations such as -v and -h should also be considered. Of course, we can do all of this with Commader.
#! /usr/bin/env node const program = require('commander') // Program.command ('create <app-name').description('create a new project').option('-f, --force','overwrite target directory if it exists') .action((name,cmd) => { console.log(anme,cmd) }) // xuan -v program .version(`cuteXuan-cli @${require('.. /package.json').version} ').usage(' <command> [option] ') // Parse (process.argv)Copy the code
Xuan Create XXX Description Some descriptors Option Some parameter configurations and short form Action What will be done after the correct command is entered
In action, name is the command and CMD is the parameter, but it is not only our parameter 🈶️, but also various default parameters. This requires parameter cleaning:
const clearArgs = (cmd) => {
const args = {}
cmd.options.forEach(element => {
const key = element.long.slice(2)
if (cmd[key]) {
args[key] =cmd[key]
}
});
return args
}
Copy the code
At this point, we can get the correct name and CMD in our action.
Of course, a scaffold will have a lot of these kinds of commands, the rest is basically drudgery. Here we only write the most important Xuan Create name and Xuan –version
Use Inquirer to interact with users
NPM I Inquirer We will encounter downloading different versions in real projects. For example, we will use different versions of Node. This is where the configuration is needed. Another example is that we need to advance some libraries for our new project, such as vuex and VuE-Router.
Of course, as mentioned earlier, we also need to make a version selection, this time we need to go to our code management address, get our version library list. Making an example: api.github.com/users/haimi…
async getTags() { let tags = await fetchTagList() if (! tags) { return } tags = tags.map(item => item.name) let {tag} = await Inquirer.prompt({ name: "tag", type: 'list', choices: tags, message: "please choose a tag to create project" }) return tag }Copy the code
Type: ‘list’ in the above code will display our tags as a list. And returns the tags of your choice.
Of course, the configuration (vuex, vue-Router) list also means the same thing, except that it becomes multi-choice, so consider giving it a try yourself!!
At this point, we have selected the project version, and we have also selected the project configuration. Next, you can monetize your choice by downloading it locally. NPM install download-git-repo It is worth mentioning that download-git-repo itself does not support Promises.
const downloadGitRepo = require('download-git-repo')
const util = require('util')
const newDownloadGitRepo util.promisify(downloadGitRepo)
Copy the code
With this approach, you can make download-Git-repo support the Promise form.
/** ** @param {*} repo template * @param {*} Tag template version */ async Download (repo,tag) {let requestUrl = `zhu-cli/${repo}${tag? '#'+tag:''}` await this.downloadGitRepo(requestUrl,path.resolve(process.cwd),`${repo}@{tag}`) return this.target }Copy the code
At this point, the scaffolding for a simple version is set up, posted on NPM, and ready to be used by others inside and outside the company. Of course, real scaffolding is much more complicated than that, and we’ve just implemented a very simple scaffold.
07 summary
At the beginning of the feature introduction, you may have been a little confused by reading this. Let’s review the CLI. Initialize the project and use the NPM link to link the scaffolding we developed to the global NPM. Use Commander to parse user input so that you can react to user input and interact with the user using Inquirer. If there is no interaction and there is no need for us to build scaffolding, isn’t it convenient to give a link directly? Use download-git-repo to download the selected content locally
If you find this article helpful, please like 👍 and follow it!!