Custom scaffolding tools solve problems

  • 1. You can customize the files to be imported.
  • 2. Custom framework selection;
  • 3. Cut yourself out of repetitive tasks.

The overall flow of scaffolding

  • 1. Generate different framework configuration files based on user input;
  • 2. Download the specified template.
  • 3. Generate different package.json according to different user information;
  • 4. Generate a new project file.

Scaffolding needs to be used with dependencies

  • 1.commander: parameter parsing tool. Use it to read the user input data, and according to the user input data to carry out certain operations.
  • 2. Inquirer: Interactive command-line tool. With it through the selection, read, judge way to read the user’s data.
  • 3. Download-git-repo: a tool for downloading remote templates. Use it to download templates configured on Git.
  • 4. Ora: The user displays the loading effect. Display a loading effect to improve user interaction friendliness.
  • 5. Chalk: Modify the color of the content printed in console.log.

Development steps

1. Initialization

  • 1. Create a project folder.
  • 2. NPM init -y initializes the project.
  • 3. Create an entry file.
  • 4. Append ‘bin’ to package.json.
  • 5. Use NPM link to link globally.


package.json

{
  "name": "wangjian-cli"."version": "2.0.0"."description": ""."main": "index.js"."bin": {
    "wangjian-cli": "./bin/app.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": []."author": ""."license": "ISC"."dependencies": {
    "axios": "^ 0.21.1"."chalk": "^ 4.1.2." "."commander": "^ 8.1.0"."download-git-repo": "^ 3.0.2." "."inquirer": "^ 8.1.2"."ora": "^ 5.4.1." "
  },
  "devDependencies": {
    "eslint": "^ 7.32.0"}}Copy the code
#! /usr/bin/env node // tells the script to be executed by node

// This file is used as the entry file for the CLI
require('.. /src/main.js');

Copy the code

2. Use commander to handle parameters

  • 1. The NPM install commander;
  • 2. The const program = the require (” commander “)


program
      .command(action) // Specify the name of the command
      .alias(alias) // Short form of configuration command
      .description(description) // Description of the configuration command
      .action(() = > {
        if (action === The '*') return console.log(chalk.red(description));
        const param = process.argv.slice(3);
        require(`./command/${action}`) (... param); });Copy the code

Create a template repository on Git

  • 1. You can create an organization on Git and download only templates within that organization.
  • 2. In CLI Create, traverse the organization’s warehouses and tags using Inquirer

Command line question and answer to achieve a dynamic configuration effect.

// Get the list of projects
const getRepoList = async() = > {const { data } = await axios.get('https://api.github.com/orgs/wangjian-cli/repos');
  const resultArr = data.map(item= > item.name);
  return resultArr;
};

// Get the version number
const getTagList = async repo => {
  const { data } = await axios.get(`https://api.github.com/repos/wangjian-cli/${repo}/tags`);
  const resultArr = data.map(item= > item.name);
  return resultArr;
};
Copy the code

Download the template from Git using the “download-git-repo” command

  • 1. The NPM install download git – ‘;
  • 2. Const downloadGitRepo = the require (” download git – ‘ ‘)
// download-git-repo Downloads the template
const download = async (repo, tag, projectName) => {
  let api = `wangjian-cli/${repo}/ `;
  if (tag) api += ` #${tag}`;
  // process.cwd() represents the folder downloaded to the currently open Node
  const dest = path.resolve(process.cwd(), projectName);
  await downloadGitRepo(api, dest);
};

Copy the code
  • 3.tips: Download -git-repo is not a promise object, you can use util to make asynchronous promises and then happily use async, await
const { promisify } = require('util');
let downloadGitRepo = require('download-git-repo');
// Convert to a Promise object
downloadGitRepo = promisify(downloadGitRepo);
Copy the code

5. Collect user data and generate package.json

const path = require('path');
const tools = require('./tools.js');
const fs = require('fs');
const { setChoices } = tools;

const setObj = async (param, projectName) => {
  const optionObj = {
    version: '1.0.0'.name: projectName,
  };
  const defaultVal = optionObj[param] || ' ';
  const tempObj = {
    type: 'input'.name: param,
    message: param,
    default: defaultVal,
  };
  const tempResult = await setChoices(tempObj);
  return tempResult;
};

const result = async projectName => {
  const file = path.resolve(process.cwd(), projectName + '/package.json');
  let data = fs.readFileSync(file, 'utf-8');
  const dataObj = JSON.parse(data);
  dataObj.version = await setObj('version');
  dataObj.author = await setObj('author');
  dataObj.name = await setObj('name', projectName);
  data = JSON.stringify(dataObj);
  fs.writeFileSync(file, data);
};
module.exports = result;
Copy the code

Publish to NPM library

  • 1. After completion, NPM login logs in to NPM.
  • 2. NPM publish publishes to the NPM library.
  • Note:
    • 1. Check whether a package with the same name exists before releasing the package.
    • 2. Switch back to official if there is taobao mirror.
    • 3. The version needs to be changed every release
  • Tips:
    • You can download NRM to manage your own NPM sources