This article will implement the development of a scaffold called create-stellarnovaui
. With just one command, npm init stellarnovaui
, you can pull the entire component library development framework to your local environment.
Create Cli Package
Firstly, we create a new cli
directory under the packages
directory, initialize it by running pnpm init
, and then change the package name to create-stellarnovaui
.
What needs to be known here is that when we execute
npm init xxx
ornpm create xxx
, we are actually executingnpx create-xxx
. So when we executenpm init stellarnovaui
, we are actually executingnpx create-stellarnovaui
.
When we execute create-stellarnovaui
, it will execute the path corresponding to bin
in package.json
. Therefore, we modify package.json
as follows.
{
"name": "create-stellarnovaui",
"version": "1.0.0",
"description": "",
"bin": "index.js",
"keywords": [],
"author": "",
"license": "MIT"
}
At the same time, create index.js
as the entry file. Note that you need to add #! /usr/bin/env node
at the beginning.
#! /usr/bin/env node
Processing User Input Commands with command-line-args
There are actually many plugins for handling user input parameters, such as CAC, Yargs, Commander.js, command-line-args, etc. However, in my view, command-line-args is the simplest to use, so here we use command-line-args for user parameter parsing.
pnpm add command-line-args
Create cli.js
to handle the logic of our scaffold. Here, let's simply write a -v
version command.
import commandLineArgs from "command-line-args";
import { readFile } from "fs/promises";
const pkg = JSON.parse(
await readFile(new URL("./package.json", import.meta.url))
);
//"Configure command parameters."
const optionDefinitions = [{ name: "version", alias: "v", type: Boolean }];
const options = commandLineArgs(optionDefinitions);
if (options.version) {
console.log(`v${pkg.version}`);
}
We can also use the command-line-usage
plugin to provide us with help commands.
pnpm add command-line-usage
Only the relevant code is posted here.
import commandLineArgs from "command-line-args"
import commandLineUsage from "command-line-usage"
...
//Help command
const helpSections = [
{
header: 'create-stellarnovaui',
content: 'A scaffold for quickly setting up a component library environment'
},
{
header: 'Options',
optionList: [
{
name: 'version',
alias: 'v',
typeLabel: '{underline boolean}',
description: 'Version number'
},
{
name: 'help',
alias: 'h',
typeLabel: '{underline boolean}',
description: 'Help'
}
]
}
];
if (options.help) {
console.log(commandLineUsage(helpSections))
return
}
Interactive Commands
When we use some scaffolding, such as create-vite, it will give us some options to choose from.
So our scaffolding should also have this feature, but how should this be implemented?
It's actually quite simple, all we need is the prompts
plugin. It can configure what the user inputs, whether it's single or multiple choices, etc.
Firstly, install prompts
.
pnpm add prompts
Then in cli.js
import prompts from "prompts";
const promptsOptions = [
{
type: "text",
name: "user",
message: "User",
},
{
type: "password",
name: "password",
message: "Password",
},
{
type: "select", //
name: "gender",
message: "Gender",
choices: [
{ title: "Male", value: 0 },
{ title: "Female", value: 1 },
],
},
{
type: "multiselect",
name: "study",
message: "Select Framework",
choices: [
{ title: "Vue", value: 0 },
{ title: "React", value: 1 },
{ title: "Angular", value: 2 },
],
},
];
const getUserInfo = async () => {
const res = await prompts(promptsOptions);
console.log(res);
};
getUserInfo();
Then we can deal with different logic based on the corresponding values. Of course, our scaffolding doesn't need so many parameters, we can change it to the following options.
const promptsOptions = [
{
type: 'text',
name: 'name',
message: 'Please enter the project name'
},
{
type: 'select', //Single Choice
name: 'template',
message: 'Please select a template',
choices: [
{ title: 'stellarnovaui', value: 1 },
{ title: 'stellarnovaui2', value: 2 }
]
}
];
Then we can pull different repositories based on the user's choices.
Pulling Remote Repository Templates
To pull remote repositories, we can use the download-git-repo
tool and use its clone
method. At the same time, we need to install a loading plugin ora
and a log color plugin chalk
.
pnpm add download-git-repo ora chalk
//gitClone.js
import download from "download-git-repo";
import chalk from "chalk";
import ora from "ora";
export default (remote, name, option) => {
const downSpinner = ora("Downloading template...").start();
return new Promise((resolve, reject) => {
download(remote, name, option, (err) => {
if (err) {
downSpinner.fail();
console.log("err", chalk.red(err));
reject(err);
return;
}
downSpinner.succeed(chalk.green("Template downloaded successfully!"));
resolve();
});
});
};
//cli.js
const remoteList = {
1: "https://github.com/markliu2013/StellarNovaUI.git",
2: "https://github.com/markliu2013/StellarNovaUI.git",
};
const getUserInfo = async () => {
const res = await prompts(promptsOptions);
if (!res.name || !res.template) return;
gitClone(`direct:${remoteList[res.template]}`, res.name, {
clone: true,
});
};
After execution, the template we need is in the directory.
Finally, we can publish our 'create-stellarnovaui'. The publishing process has been introduced before, so I won't go into detail here. I have already published it, so let's try to run 'npm create stellarnovaui' in any folder. You can see stellarnovaui will be cloned.
The final source code: https://github.com/markliu2013/StellarNovaUI
Top comments (0)