Record – Develop a scaffold

Function:

  • Similar to vue-CLI, through a command such asvue create hello-world, and then according to step by step tips, finally pull the corresponding content

Development reasons:

  • There is a template project in line with its own business logic inside the front-end group. In order to facilitate the group members to quickly pull it, a scaffold is needed.
  • Once the scaffold is up, templates to suit different needs can also be added to the scaffold
  • Different templates can be easily managed with Git

Effect:

The tool platform is still used: internal front-end tool platform setup, installation: NPM i-g@mycompany /feTools

Terminal input: fe cli (tips: start cli) Print: a hint:? Please enter the file name you want to create (it will be created in the current directory) : (cli-project) (tips: enter the file name you want to create, or use the default name cli-project) Please select the template you want to pull: (Use arrow keys) (Tips: Select the template you want to pull up and down) ❯ vue2 test Press Enter to end (the file has been pulled to the current directory)Copy the code

Development Principle Analysis

Difficult points:

  • In order to clarify the step – by – step functional operations, different tool libraries are required to support

The tool library combination supports the following:

  1. Commander: identifies the command, for example, fe cli -h
  2. Inquirer: Terminal interaction. You can enter a file name and select a template
  3. Download-git-repo: Pull the gitLab library. Similar to git clone
  4. Others, such as NPM install

Source:

Entry. js: entry file

#! /usr/bin/env node
// Configure the current environment variable address: MAC is fixed

// Introduce dependencies
const commander = require('commander') / / a complete node. Js command-line solution: https://www.npmjs.com/package/commander
const createProject = require('./create-project') // The next step is to see
const inquirer = require('inquirer') / / command line interactive tool: https://www.npmjs.com/package/inquirer
const pkgJson = require('.. /.. /package.json')

// Define the version number and command options
commander
  .version(pkgJson.version, '-v -V --version') // If you don't write the following, you can only use capital V
  .option('-i --init [name]'.'init a project')
  .parse(process.argv) // let commander can get process.argv

const promptList = [{
  type: 'input'.message: 'Please enter the filename you want to create (it will be created in the current directory) :'.name: 'name'.default: 'cli-project' / / the default value
}]

let projectName = ' '
if (commander.init) { // if cli -i xxName, go here
  projectName = commander.init
  createProject(projectName)
} else { // Go to the cli
  inquirer.prompt(promptList).then(answers= > {
    projectName = answers.name ? answers.name : 'cli-project'
    createProject(projectName) // Get the file name})}Copy the code

Create-project. js: configures user option interaction

const chalk = require('chalk') . / / color the console log
const path = require('path') // Get the path
const inquirer = require('inquirer')
const GitClone = require('./git-clone.js') // The next step is to see
const npmInstall = require('./npm-install.js') LNPM I is executed from the command line without affecting the main function

const promptList = [{
  type: 'list'.message: 'Please select the template you want to pull :'.name: 'key'.choices: [].filter: function (val) { // filter result
    return val
  }
}]

GitClone.tplObj.map(e= > {
  promptList[0].choices.push(e.key) // Add the git template to the promptList, which is executed by the Inquirer
})

module.exports = function createProject (name) {
  inquirer.prompt(promptList).then(answers= > {
    // Get the root directory of the project to build
    const projectPath = path.resolve(name) // return absolute path
    console.log(`Start to init a project in ${chalk.green(projectPath)}`)

    const key = answers.key
    Git clone
    GitClone.gitCloneFn(key, name)
      .then(msg= > {
        console.log(chalk.green(msg))

        // The editor can comment out NPM install because it is easy to freeze after the larger template NPM install
        npmInstall(projectPath)
      })
      .catch(err= > {
        if (err.includes('128')) {
          console.log(chalk.red(` failed!${name}Existing '))}else {
          console.log(chalk.red(err))
        }
      })
  })
}
Copy the code

Git-clone. js: Use Git Clone to pull the project down. The template can be configured here

const download = require('download-git-repo') / / execution git clone code: https://www.npmjs.com/package/download-git-repo

const tplObj = [
  {
    key: 'vue2'.git: 'https://gitlab.xxx.cn/xxxx/xxxx.git#vue2' // #vue2 represents the vue2 branch
  },
  {
    key: 'test'.git: 'https://gitlab.xxx.cn/xxxx/test.git'}]const gitCloneFn = (key, tplName) = > {
  return new Promise((resolve, reject) = > {
    const obj = tplObj.find(e= > e.key === key)
    download('direct:' + obj.git, tplName, { clone: true }, function (err) {
      const msg = 'Pull up to date${obj.git}: `
      if (err) {
        reject(`${msg}: Error: ${err}`)}else {
        resolve(`${msg}: Success`)}})})}module.exports = {
  tplObj,
  gitCloneFn
}
Copy the code

NPM -install.js: Run NPM install

// Introduce dependencies
const which = require('which') // Check whether there is a global variable in the current environment (computer environment)
const chalk = require('chalk')

const { spawn } = require('child_process') // Run the LNPM I command

// Start the child process to execute the NPM install command
function runCommand (command, args, fn) {
  args = args || []
  const runner = spawn(command, args, {
    stdio: 'inherit' // (inherits the stdio output of the parent process) prints information about NPM install
  })

  runner.on('close'.function (code) {
    if (fn) {
      fn(code)
    }
  })
}

// Find the command used to install dependency packages in the system
function findNpm () {
  const npms = ['lnpm'.'cnpm'.'npm']
  for (let i = 0; i < npms.length; i++) {
    try {
      // Find the first instance of the executable specified under the environment variable
      which.sync(npms[i])
      console.log('use npm: ' + npms[i])
      return npms[i]
    } catch (e) {
    }
  }
  throw new Error(chalk.red('please install lnpm'))}module.exports = function npmInstall (projectPath) {
  console.log('Installing packages... ')
  // Change the Node working directory to the build project root directory
  process.chdir(projectPath)

  setTimeout(() = > {
    const npm = findNpm()
    runCommand(which.sync(npm), ['install'].function () {
      console.log(npm + ' install end')})},1000)}Copy the code

Code word is not easy, little praise to encourage