First of all, I wish you a happy New Year with my family.

This talk focuses on the PLOP automation template feature. The internal gateway project of the company is used to carry out this practice. In order to facilitate the understanding of the project structure, the project structure is briefly described as follows:

An API gateway is a service in a microservices architecture that provides a shared layer and API for clients to communicate with internal services. We can provide gateway services for PCS, applets, and public apis, which are interfaces from multiple other microservices.

In our actual project, the convention for directory structures is as follows:

According to the structure of the official website, the actual business is divided into service modules:

At this time, a lot of repetitive work occurs. When 1 service is added, 2 folders and 3 files need to be manually created. When 1 interface is added, 3 associated calls are manually added.

So how to solve this problem? A certain technology and said, we have to use the code to solve code brings pain points, in the process of we to code the farmers themselves, never self-pity, 2022 of the friend, don’t again with a male plow female woven way for development, we must learn to use a variety of tools to improve productivity, increase output, out of time water, feel the fish is bad?

After paving the way, let’s talk about how to solve the pain point of male ploughing and female weaving: automation.

For repetitive tasks such as: Add routing, a group of new configuration, component library development, a large number of structure is consistent page, create a single test clips and so on scene, we all make machine instead of manual must be considered, while the mind is no problem, but before mass production, efficiency and quality, more accurate, automated processing can do for the specification code also has a lot of help, use of automatic abstract template, Produce the same and different code ~

Here’s the thing: What is the Plop artifact? You can go to the documentation github.com/plopjs/plop

Next, I will post the process of my configuration to you for your reference (entry-level introduction, big guys light injection). This time, I mainly introduce two scenarios of directly generating content with templates and adding content output from templates to existing content files.

NPM install –save-dev plop

Then add a line “plop” to scripts in package.json: “plop”

Run NPM run plop directly

Create plopfile.js, plop-template, plop-template, plop-template, plop-template, plop-template, plop-template, plop-template, plop-template, plop-template. Create the corresponding template.

This is my directory structure posted at the end. If your project path changes, please modify your path strictly.

Add the following code:

/ / create the add
const addGenerator = require('./plop-template/add/prompt.js');
module.exports = function(plop) {
  plop.setGenerator('add', addGenerator);
};
Copy the code

Scenario 1: Create file add First we add the controller file command configuration

module.exports = {
  description: 'Create a New Service Configuration'.// Describe the effect of generate
  prompts: [{
    type: 'input'.// The type of problem
    name: 'moduleName'.// The question corresponds to the variable name of the answer, which can be used in acitons
    message: 'File name :'.// A problem at the command line
    default: 'pages'.validate: moduleName= > {
      const reg = /^[^0-9][a-zA-Z0-9_]+$/;
      returnreg.test(moduleName); }}],actions: data= > { // Here you can get the input pathname from data
    const { moduleName } = data;
    const bigModuleName = moduleName.charAt(0).toUpperCase() + moduleName.slice(1);
    const actions = [
      {
        type: 'add'.// Operation type Add file
        path: `app/controller/${moduleName}/index.js`.// The path to the added file
        templateFile: 'plop-template/add/controller.hbs'.// Template file path
        data: {
          name: moduleName,
          Name: bigModuleName,
        },
      }
    ];
    returnactions; }};Copy the code

So that’s the ploP command configuration; We’ve already introduced this file in plopfile.js, which will be parsed when we execute plop; Prompts. Prompts. Description is the name of the current action. Prompt configuration is the configuration of the command in the question and answer mode. Action is the basis for action such as creating a template, adding and modifying the parameters collected in the user question and answer mode.

Create controller.hbs, so our controller template says,

'use strict';

const Controller = require('egg').Controller;


class {{ Name }}Controller extends Controller {
  constructor(config) {
    super(config);
    this.service{{ Name }} = this.ctx.service.{{ name }}.index;
  }
  // -- APPEND HERE --
  / * * *@params* /
  async index() {
    this.ctx.body = await this.service{{Name}}.index(); }}module.exports = {{ Name }}Controller;

Copy the code

It is known that Name and Name are passed as parameters in the configuration, so the corresponding parameters will be displayed in the pulled template. // — APPEND HERE — is a placeholder for subsequent appends, which we’ll talk about later;

At this point a complete example is complete, and I have added the service and Router configuration and templates accordingly. We can try NPM run plop and see if the console tells us that the content succeeded.

Step 1 q&A:

The look of success

Let’s look at the output

It’s not bad. It’s what I want.

If something goes wrong, it doesn’t matter, the error message still tells us what went wrong, right

If you succeed, congratulations, we can move on to the next example;

Scenario 2: Append or modify content

We have created the js file from the previous example, so how do we append the new interface?

There are several ways to APPEND content to a plop command, and I’m using —–modify with placeholders (// — APPEND HERE –) in the most awkward and direct way.

Let’s take a look at the process of writing the append command, first adding it in the appropriate place in plopfile.js

const appendGenerator = require('./plop-template/append/prompt.js');
Copy the code
plop.setGenerator('append', appendGenerator);
Copy the code

Prompt. Js in the append folder

'use strict';
module.exports = {
  description: 'Add a new interface'.// Describe the effect of generate
  prompts: [{
    type: 'input'.// The type of problem
    name: 'serviceName'.// The question corresponds to the variable name of the answer, which can be used in acitons
    message: 'Which service to add a new interface to :'.// A problem at the command line
    default: 'bsvc'.validate: serviceName= > {
      const reg = /^[^0-9][a-zA-Z0-9_]+$/;
      returnreg.test(serviceName); }, {},type: 'input'.// The type of problem
    name: 'pathname'.// The question corresponds to the variable name of the answer, which can be used in acitons
    message: More than 'path name, separated by a comma (eg: the controller, the service, the router)'.// A problem at the command line
    default: 'controller,service,router'}, {type: 'input'.// The type of problem
    name: 'interfaceName'.// The question corresponds to the variable name of the answer, which can be used in acitons
    message: 'Interface name, separated by commas (eg: getUsers,getList)'.// A problem at the command line
    default: 'getUsers',}],actions: data= > { // Here you can get the input pathname from data
    const { interfaceName, serviceName, pathname } = data;
    const bigInterfaceName = interfaceName.charAt(0).toUpperCase() + interfaceName.slice(1);
    const bigServiceName = serviceName.charAt(0).toUpperCase() + serviceName.slice(1);
    const pathnameList = pathname.split(', ');
    const actions = [];
    if (pathnameList.includes('controller')) {
      actions.push({
        type: 'modify'.// Operation type Add file
        path: `app/controller/${serviceName}/index.js`.// The path to the added file
        templateFile: 'plop-template/append/controller.hbs'.// Template file path
        pattern: /(\/\/ -- APPEND HERE --)/gi,
        data: {
          name: serviceName,
          Name: bigServiceName,
          interfaceInfo: {
            interfaceName,
            bigInterfaceName,
          },
        },
      });
    }
    if (pathnameList.includes('service')) {
      actions.push({
        type: 'modify'.// Operation type Add file
        path: `app/service/${serviceName}/index.js`.// The path to the added file
        templateFile: 'plop-template/append/service.hbs'.// Template file path
        pattern: /(\/\/ -- APPEND HERE --)/gi,
        data: {
          name: serviceName,
          Name: bigServiceName,
          interfaceInfo: {
            interfaceName,
            bigInterfaceName,
          },
        },
      });
    }
    if (pathnameList.includes('router')) {
      actions.push({
        type: 'modify'.// Operation type Add file
        path: `app/router/${serviceName}.js`.// The path to the added file
        templateFile: 'plop-template/append/router.hbs'.// Template file path
        pattern: /(\/\/ -- APPEND HERE --)/gi,
        data: {
          name: serviceName,
          Name: bigServiceName,
          interfaceInfo: {
            interfaceName,
            bigInterfaceName,
          },
        },
      });
    }
    returnactions; }};Copy the code

Configuration commands that you probably understand most of from the last example,

In the action we added the pattern: /(// — APPEND HERE –)/gi parameter to repalce the pattern corresponding to ‘modify’

OK Execute NPM run plop again and you will notice that our command action has been increased by one

The execution result

Note that // — APPEND HERE — the placeholder should always be carried, or who will you replace next, right

Through the above examples, the template automation practice is over, sa hua 🎉

The last day of this year, the nuggets MOE new, offering the first article, the writing is not good, please forgive, the above code has more need to optimize the content, only for the first time to try the students to view, also ask you to correct.