1. Understanding of scaffolding

1. The role of scaffolding

Projects of the same type tend to have a lot of similarities, and scaffolding tools are designed to help us get the infrastructure of a project quickly because of the “rework” caused by these similarities.

Examples of this similarity are the vUE project code

  • Same basic code. Example: vueRouter initialization, vuex initialization, vUE instance creation, app. vue component global route exit, etc
  • Same module dependencies. Vuex, vueRouter, Webpack, Sass, Babel, etc
  • Same tool configuration. Babel, Gitignore and so on
  • Same development paradigm.
  • Same organizational structure. Organizational structure of the project.

Two, Yeoman’s understanding

Yeoman is a front-end scaffolding tool for common projects, unlike vue-CLI, which is only for Vue projects. Yeoman is more flexible. Different generators can be used to compose different projects (webApp, Node project) scaffolding, and we can also define our own scaffolding tools.

Third, basic use of Yeoman

Yeoman = YO + variable Generator can generate different application scaffolding tools

  • Using Yeoman requires yo to be installed globally
  • Finding the corresponding generator
  • Run the generator with yo

1. Create an example of a Node project

  1. Installing yukio okamoto,
yarn global add yo
Copy the code
  1. Go to yeoman’s official website to find the corresponding Node Generator and install it
yarn global add generator-node
Copy the code

PS:generator-The corresponding module name is concatenated with the prefix, such as node3. Run the installed Generator – Node module with the yo command to obtain the infrastructure of the generated Node project according to a series of configurations of the generator-node (refer to the questions asked in the following figure)

2. Sub Generator

The subgenerator module is designed to generate configuration files such as esLint, EditorConfig, etc., on top of the project structure generated by the Generator. Not every Generator has a Sub Generator. This requires the Generator to be able to provide a Sub Generator.

Generate the EditorConfig example:

Before:First let’s clear the configuration of the existing EditorConfigafter:

// Run yo + Generator module name + : + Sub Generator name (go to the official location of the corresponding generator) yo Node: EditorConfigCopy the code

We’ll be prompted if we want to override this file, so we’ll select y.At this point we look at the EditorConfig file again, and it’s changed.Sometimes when we write these configuration files by hand, we often make mistakes, we don’t remember so much. At this point we can check to see if the corresponding generator provides a sub generator to generate these configuration files

3. Yeoman’s summary

  • Find the Generator based on the type of project we need
  • Install the Generator globally
  • Use the Generator with the yo command
  • Complete the interaction commands provided by the Generator to generate the project structure we need

Custom Generator

1. Create your own Generator

A custom Generator is essentially an NPM module

  1. Create a file with the current package name as generator- XXX, run Yarn init, and install Yeoman-Genenrator

  1. Create the infrastructure for a custom Generator

3. Introduce the Yeoman-Generator in the entry index.js file as the base class to generate your own classes, and the templates file as the output template. See the code below for an explanation.

// This file serves as the core entry for the Generator
 
// 1. A base class such as Yeoman-generator is needed
const Generator = require('yeoman-generator')

// 2. Create our own genenrator class, then inherit from the base class, and finally export the type we created.
// The entry file is automatically executed when we pass the yo generator name, calling the lifecycle of the class we created and exported to do something like build the project infrastructure in Writing
module.exports = class extends Generator {
  // 3. If you need to ask the user a command-line interaction question about how the heavily-guarded infrastructure is generated, can you use the Heavily-guarded method
  prompting() {
    // 4. the prompt method returns a Promise object
    return this.prompt([
      { 
        type: 'input'.// Interaction type
        name: 'name'.// The name of the variable used to store the current input value
        message: 'Your project name ? '.// Problem name
        default: this.appname // By default, this.appname is the name of the file to run our custom Generator with yo
      }
    ])
    .then(answers= > {
      // 5. Store the answers to the questions we get in the this.answer variable so that we can use them later when building the project infrastructure.
      this.answers = answers
    })
  }

  // 6. The writing method is used to generate project files
  // 7. Yeoman-generator allows us to generate the project infrastructure in the form of templates. Create a template folder with generators/app/ and place all the project files we need to generate in this folder.
  // 8. Since the project infrastructure is generated by the template engine, you can "dig" the template syntax of the template engine, such as <%= name%>. If you want to output <%= name%>, you can translate it by adding another %, such as <%%=name%>.
  writing() {
    // 9. Translate each file in the templates file to the target path
    // Define the relative path of each file as an array, and iterate through the template to generate the target path
    const templates = [
      '.gitignore'.'babel.config.js'.'package.json'.'package-lock.json'.'README.md'.'src/assets/logo.png'.'src/components/HelloWorld.vue'.'src/components/Calendar/index.vue'.'src/components/Calendar/utils.js'.'src/App.vue'.'src/main.js'.'public/favicon.ico'.'public/index.html'
    ]

    templates.forEach(item= > {
      // item for each file path
      // 10. Use the fs.copyType provided by the base class Yeoman-Generator to generate files for our own project
      // fs.copyType(template path, your own project output target path, template parameters) parameters
      // 
      this.fs.copyTpl(
        this.templatePath(item),
        this.destinationPath(item),
        this.answers
      )
    })
  }

}
Copy the code

  1. Since YO needs to run our custom generator, running YARN Link in the current custom generator will enable YO to run.
  2. Run yukio okamoto, reborn

The version of Yeoman-Generator needs to be reduced to 4.0 if the following problems are encounteredThe result of the runAt this point you generate your own scaffold with a custom generator

2. Release the Generator

Publishing a custom Generator is essentially publishing an NPM module

Run yarn Publish to publish

Note That the current NPM YARN source cannot be the source of the Taobao image. You need to change the original source address.

After the release is successful, you can install it using NPM Yarn

Fifth, the Plop

1. The introduction of the plop

The main purpose of a small and beautiful little scaffolding tool is to generate some repetitive file code of a specific type from template code as shown in the following example:

2. Basic use of PLOP

Blog.csdn.net/u012733501/…

  1. Install the NPM package
yarn add plop -D
Copy the code
  1. Create the configuration file plopfile.js in the root directory of the project
// When we run the plop command, we will use this file as the entry file, from which we need to export a function.

// 1. Export a function to create the generator task. This function accepts a plop object to create the generator task
module.exports = plop= > {
  Set the Generator. This function takes two arguments. The first argument is the name of the Generator (also the name of the command plop runs), and the second argument is the config object.

  plop.setGenerator('component', {   
    description: 'Create a component'.Prompts interact with the user's command line
    prompts: [{type: 'input'.// Interaction type
        name: 'name'.// The name of the variable, which stores the information entered by the user
        message: 'component name'./ / the problem
        validate(val) {
          // Val is the input value
          // If the validation fails, return a string, which will be displayed in the console
          // Return true
          return true;
        },
        default: 'reborn'}].// 4. The action to be performed after the command line interaction is complete
    // 5. You need to use plap-templates in the root directory of your project to store the plop template. Plop uses handlebars as the template for processing the template code
    actions: [{// Add a new file
        type: 'add'.// The file path to be added, which can be interpolated, is derived from the input obtained during command-line interaction with the user.
        path: 'src/components/{{name}}/{{name}}.js'.// Template file
        templateFile: 'plop-templates/component.hbs'
      },
      {
        type: 'add'.path: 'src/components/{{name}}/{{name}}.css'.templateFile: 'plop-templates/component.css.hbs'
      },
      {
        type: 'add'.path: 'src/components/{{name}}/{{name}}.vue'.templateFile: 'plop-templates/components.vue.hbs'})}},]Copy the code

  1. Run the scaffolding task through the CLI provided by PLOP

At this point, three files are created from the templateHandlebars template The output

Working principle of scaffolding

1. Encapsulate your own scaffolding tools

  1. Initialize a package.json
  2. You need to add a bin attribute in the package.json file to specify an entry file cli.js for the CLI.

3. See the code below for details

#! /usr/bin/env node

// The Node CLI application entry file must have this header
// In Linux or macOS, you need to change the read/write permission of this file to 755
Chmod 755 cli.js

// The working process of scaffolding:
// 1. Ask the user interactive questions through the command line
// 2. Generate files based on the results of questions answered by users

const inquirer = require('inquirer')
const path = require('path')
const fs = require('fs')
const ejs = require('ejs')
// 1. Ask the user interactive questions through the command line
inquirer.prompt([
  / / input type
  {
    type: 'input'.name: 'name'.message: 'project name? '.validate(val) {
      console.log(val)
      if(! val) {return 'Please enter'
      } else {
        return true
      }
    }
  },

]).then(answer= > {
  // 2. According to the answer result => Combine the inquirer result with the template file under template and the EJS template engine to get the combined template, and then write it to the directory where the tool runs.
  
  // The template directory
  const tmplDir = path.join(__dirname, 'templates')
  // Output directory
  const destDir = process.cwd()

  // Convert all files in the template to the target directory
  // The readdir method scans all files in the target path to get an array of file names
  fs.readdir(tmplDir, (err, files) = > {
    if (err) throw err
    files.forEach(file= > {
      // Render the file corresponding to the path through the template engine
      ejs.renderFile(path.join(tmplDir, file), answer, (err, result) = > {
        if (err) throw err
        
        // Write the result of the template
        fs.writeFileSync(path.join(destDir, file), result)
      })
    })
  })
})

Copy the code
  1. To get the object file, run the scaffolding command

2. Summary of the working principle of scaffolding

The function of scaffolding is to help us quickly get the infrastructure of a project or generate a specific document. The function of scaffolding is to solve the “duplication of labor”. In generate specific repetitive file (code), often can’t is “rigid”, this needs through a command line interactive tools that we know the user ta want what file (code), we want in the user through the template engine tools to compose and the content of the output, thus get the results we want.