• Column address: Front-end compilation and engineering
  • Author: Jiao Yang 2019

The background,

When we add modules or subprojects to a large front-end project, we often do a lot of boring, repetitive initialization first. For example, to add a new page, you need to add corresponding component files, routes, and dependency import to the new page. Having a tool that automates one-click creation of pages and code can save a lot of time while avoiding manual coding errors is a great aid in our development efforts.

Ii. Comparison of schemes

An automated scaffold is essentially a simple program written in a particular scripting language. This program can be executed according to the skeleton structure of the project, code specifications, and some component templates, to create a code file specifying a new module or subproject and fill some code fragments. In theory, it can be implemented using any language that calls operating system apis, such as C, Java, Bash, Node.js, etc. Given the scenarios we use, we need a more lightweight way to do this, and shell and Node.js are better choices. We made a comparison between the two implementations:

Compare the item bash Node.js
Getting started difficulty (for the front end) A little difficult easy
Integration with front-end engineering general Good (essentially implemented in the JavaScript language)
Environment compatibility Native support under Unix/Linux, Windows requires a specific bash environment to be installed It is not supported natively on all platforms, but can be used across platforms with Node installed

Based on these comparisons, we found that using Node.js as the development language for project scaffolding has advantages over using Bash in front-end engineering.

Node.js implementation of common libraries and functions

1. Global Global variables

Global variables are available in all modules. For example: require, console, __dirname, process, etc

  • require(id)

Used to import modules, JSON or local files. Local modules and local files can be imported using relative paths that are resolved according to the __dirname directory or the current working directory. In this case, it is used to import the FS and PATH modules.

let fs = require('fs');
let path = require('path');
Copy the code
  • console

A simple debug console for providing console output. This example uses console.log() : prints characters to the standard output stream, ending with a newline character. In this example, an error is displayed if the user does not enter the module name, submodule name, and page name at the same time.

If (args.length < 3) {console.log(' module name, submodule name, page name required '); process.exit(0); }Copy the code
  • __dirname

Indicates the directory where the script is currently executed. In this example, the command is used to obtain the directory where the script is running.

if (type === 'form' || type === 'table') {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/form_tpl.vue' : './template/table_tpl.vue'), 'utf8');
    apiTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/api_form.js' : './template/api_table.js'), 'utf8');
    constTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/const_form.js' : './template/const_table.js'), 'utf8');
    if (type === 'table') {
        modalTpl = fs.readFileSync(path.join(__dirname, './template/addEditModal.vue'), 'utf8'); }}else {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, './template/template.vue'), 'utf8');
}
Copy the code
  • process

See process for details.

2. The process of the process

The Process object provides information about and controls the current Node.js process. It is available globally, and the official website recommends referencing it via require or import.

import process from 'process';
Copy the code

The Process object provides a number of events that are not covered in this discussion. If you are interested, check out the official website.

  • process.argv

The process.argv property returns an array of parameters passed in when the user started the process. The first element is the absolute pathname of the executable that started the Node.js process, and the second element is the path of the Javascript file being executed. The other elements are command-line arguments. In this case, to get the module name, submodule name, and page name entered by the user.

let args = process.argv.splice(2);
Copy the code

Suppose the main.js script looks like this:

process.argv.forEach((val, index) = > {
  console.log(`${index}: ${val}`);
});
Copy the code

After the process is started, the following output is displayed:

  • process.exit([code])

Process.exit () means node.js exits and synchronously terminates the process with code. Code can be omitted. In this case, success code 0 is used. Calling this method forces the process to exit as soon as possible, even if there are still pending asynchronous operations that have not completely completed. In this case, to get the module name, submodule name, and page name entered by the user. In this example, if the user does not enter the module name, submodule name, and page name at the same time, the user is forced to exit.

if (args.length < 3) {
    console.log('Module name, sub-module name, page name Required');
    process.exit(0);
}
Copy the code

3. The path of the path

The path module provides tools for handling paths to files and directories as follows:

const path = require('path');
Copy the code
  • path.join()

Path.join () joins all given path fragments together using platform delimiters as delimiters to generate paths. In this example, the command is used to combine directories based on the directory where the script is running.

if (type === 'form' || type === 'table') {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/form_tpl.vue' : './template/table_tpl.vue'), 'utf8');
    apiTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/api_form.js' : './template/api_table.js'), 'utf8');
    constTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/const_form.js' : './template/const_table.js'), 'utf8');
    if (type === 'table') {
        modalTpl = fs.readFileSync(path.join(__dirname, './template/addEditModal.vue'), 'utf8'); }}else {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, './template/template.vue'), 'utf8');
}
Copy the code

4. Fs file system classification

Node.js has synchronous and asynchronous file system operations. In synchronous mode, the main process directly calls the API of the file system, which may cause the process to block. In asynchronous mode, the blocked process is transferred to the child process, and the main process can continue to process other operations.

Create input.txt and create files.js with the following contents:

var fs = require("fs");

// read
fs.readFile('input.txt'.function (err, data) {
   if (err) {
       return console.error(err);
   }
   console.log("read: " + data.toString());
});

// read sync
var data = fs.readFileSync('input.txt');
console.log("read sync: " + data.toString());

console.log("finish");
Copy the code

The running results are as follows:

5. Fs file system

Import file system syntax:

const fs = require("fs")
Copy the code
Method names fs.existsSync fs.mkdirSync fs.readFileSync fs.writeFileSync
role Checks whether the given path exists. Create a directory synchronously. Reading file contents Synchronously read file contents
The return value Return true if the path exists, false otherwise. Returns the contents of path Returns the undefined
Asynchronous methods fs.exists fs.mkdir fs.readFile fs.writeFile
This example role Used to determine whether the module, submodule, page folder exists. Used to create modules, submodules, and page folders. Used to read template content. Used to write converted content to the target file.
  • fs.readFileSync(path [, options])

Parameters: path: file name or file descriptor; Options: object or string containing {encoding, flag} by default. The default encoding is null and flag is ‘r'(open file in read mode. Throw an exception if the file does not exist)

  • fs.writeFileSync(file, data[, options])

Parameters: file: file name or file descriptor; Data: data to be written to a file. Options: object or string containing {encoding, mode, flag} by default. Default encoding utF8, mode 0666, flag ‘w'(opens file in write mode, creates file if it doesn’t exist)

// Create a new module folder
if(! fs.existsSync(`${controllerPath}/${module1}`)) {
    fs.mkdirSync(`${controllerPath}/${module1}`);
    fs.mkdirSync(`${viewPath}/${module1}`);
}

// Create a new submodule folder
if(! fs.existsSync(`${controllerPath}/${module1}/${submodule}`)) {
    fs.mkdirSync(`${controllerPath}/${module1}/${submodule}`);
    fs.mkdirSync(`${viewPath}/${module1}/${submodule}`);
}

// Create a page folder
if(! fs.existsSync(`${viewPath}/${module1}/${submodule}/${page}`)) {
    fs.mkdirSync(`${viewPath}/${module1}/${submodule}/${page}`);
}

// Add permission to modeEngine file
let authOrigin = fs.readFileSync(path.join(__dirname, './template/auth.js'), 'utf8');
let formatAuth1 = authOrigin.replace(/module1/g, module1);
let formatAuth2 = formatAuth1.replace(/submodule/g, submodule);
let auth = formatAuth2.replace(/page/g, page);
let data = fs.readFileSync(path.join(__dirname, '. / apps/modeEngine. Js, '), 'utf8').split(/break; /gm);
data.splice(data.length - 2.0, auth);
fs.writeFileSync('./apps/modeEngine.js', data.join('break; '));
Copy the code

4. Node.js implementation case

Create a directory and create a template in the Ext package Vue project.

  1. The user needs to enter at least three parameters: module name, submodule name, and page name. If the parameters are less than three, an error message is displayed to exit the script.
  2. Allow the user to enter a fourth parameter, which creates an empty template if it is null, a TABLE template if it is TABLE, and a form template if it is form.
  3. The controller folder and View folder need to be created. The path is the parameter entered by the user. If the path does not exist, create the controller folder.
  4. The content read from the template must be written to the newly created template after the parameters entered by the user are replaced with corresponding values.
  5. At the same time, add the permission on the routing page
/ * * *@fileOverview  Automatically create a directory */

let fs = require('fs');
let path = require('path');

let args = process.argv.splice(2);

if (args.length < 3) {
    console.log('Module name, sub-module name, page name Required');
    process.exit(0);
}

// Define the receive variable
let module1 = args[0];
let submodule = args[1];
let page = args[2];
let type = args[3];

// Define the file path variable
let controllerPath = './apps/controller';
let controllerPagePath = `${controllerPath}/${module1}/${submodule}/${page}.js`;
let viewPath = './apps/view';
let viewPanelPath = `${viewPath}/${module1}/${submodule}/${page}/Panel.js`;
let viewIndexPath = `${viewPath}/${module1}/${submodule}/${page}/index.vue`;
let viewConstPath = `${viewPath}/${module1}/${submodule}/${page}/const.js`;
let viewApiPath = `${viewPath}/${module1}/${submodule}/${page}/api.js`;
let viewModalPath = `${viewPath}/${module1}/${submodule}/${page}/addEditModal.vue`;

// Create a new module folder
if(! fs.existsSync(`${controllerPath}/${module1}`)) {
    fs.mkdirSync(`${controllerPath}/${module1}`);
    fs.mkdirSync(`${viewPath}/${module1}`);
}

// Create a new submodule folder
if(! fs.existsSync(`${controllerPath}/${module1}/${submodule}`)) {
    fs.mkdirSync(`${controllerPath}/${module1}/${submodule}`);
    fs.mkdirSync(`${viewPath}/${module1}/${submodule}`);
}

// Create a page folder
if(! fs.existsSync(`${viewPath}/${module1}/${submodule}/${page}`)) {
    fs.mkdirSync(`${viewPath}/${module1}/${submodule}/${page}`);
}

// Read the Controller template file and modify the contents
let controllerTplOrigin = fs.readFileSync(path.join(__dirname, './template/controller_tpl.js'), 'utf8');
let formatConTpl1 = controllerTplOrigin.replace(/submodule/g, submodule);
let formatConTpl2 = formatConTpl1.replace(/module/g, module1);
let controllerTpl = formatConTpl2.replace(/page/g, page);

// Read the panel template file and modify the contents
let panelTplOrigin = fs.readFileSync(path.join(__dirname, './template/panel_tpl.js'), 'utf8');
let formatPanelTpl1 = panelTplOrigin.replace(/submodule/g, submodule);
let formatPanelTpl2 = formatPanelTpl1.replace(/module/g, module1);
let panelTpl = formatPanelTpl2.replace(/page/g, page);

// Read the vue template file and modify the contents
let indexTplOrigin = ' ';
let apiTpl = ' ';
let constTpl = ' ';
let modalTpl = ' ';
if (type === 'form' || type === 'table') {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/form_tpl.vue' : './template/table_tpl.vue'), 'utf8');
    apiTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/api_form.js' : './template/api_table.js'), 'utf8');
    constTpl = fs.readFileSync(path.join(__dirname, type === 'form' ? './template/const_form.js' : './template/const_table.js'), 'utf8');
    if (type === 'table') {
        modalTpl = fs.readFileSync(path.join(__dirname, './template/addEditModal.vue'), 'utf8'); }}else {
    indexTplOrigin = fs.readFileSync(path.join(__dirname, './template/template.vue'), 'utf8');
}

let indexTpl = indexTplOrigin.replace(/page\b/g, page);

// Create a route and page file
if(! fs.existsSync(`${controllerPagePath}`)) {
    fs.writeFileSync(`${controllerPagePath}`, controllerTpl);
    fs.writeFileSync(`${viewPanelPath}`, panelTpl);
    fs.writeFileSync(`${viewIndexPath}`, indexTpl);
    if (type === 'form' || type === 'table') {
        fs.writeFileSync(`${viewApiPath}`, apiTpl);
        fs.writeFileSync(`${viewConstPath}`, constTpl);
        if (type === 'table') {
            fs.writeFileSync(`${viewModalPath}`, modalTpl); }}}else {
    console.error('error! \n' + controllerPagePath + ' has already been existed! ');
}

// Add permission to modeEngine file
let authOrigin = fs.readFileSync(path.join(__dirname, './template/auth.js'), 'utf8');
let formatAuth1 = authOrigin.replace(/module1/g, module1);
let formatAuth2 = formatAuth1.replace(/submodule/g, submodule);
let auth = formatAuth2.replace(/page/g, page);
let data = fs.readFileSync(path.join(__dirname, '. / apps/modeEngine. Js, '), 'utf8').split(/break; /gm);
data.splice(data.length - 2.0, auth);
fs.writeFileSync('./apps/modeEngine.js', data.join('break; '));

process.exit(0);
Copy the code

An empty template:

<template> <div class="page">page</div> </template> <script lang="ts"> /** * @fileOverview page */ import {Component, Mixins, Watch, Prop} from 'vue-property-decorator'; @Component({ components: {}, mixins: [] }) export default class page extends Mixins() { @Prop({ default: false }) disabled! : boolean; Private List = []; @Watch("list", { deep: true }) handleListChange() {} mounted () {} listChange () {} } </script> <style lang="less" scoped> </style>Copy the code

Five, shell implementation of common commands and syntax introduction

1. Definition and operation of shell

  • define

Shell definitions start with #! / bin/sh, #! Tell the system what interpreter the script needs to execute, that is, what shell to use.

#! /bin/bash
echo "Hello World !"
Copy the code
  • run

Add the execute permission to chmod + x. /xxxx.sh

Run the./xxxx.sh script

2. Shell variables

  • Define variables

When defining a variable, the variable name is not marked with the $sign. The following

message = "hello world"
Copy the code

When defining string types, you can use double or single quotation marks. The difference is that double quotes can contain variables and escapes, while single quotes are printed as they are.

Naming rules for variable names:

  • The name must contain only letters, digits, and underscores (_). The first character cannot start with a number.

  • There can be no Spaces between them. Instead, use the underscore _.

  • Do not use punctuation marks.

  • You can’t use keywords in bash (see the help command for reserved keywords).

  • Use the variable

To use a variable, you simply add the $sign to the name of the defined variable, as follows

message = 'hello world';
echo ${text};
Copy the code

Variable names with {} are optional and recommended for clearer structure and to avoid parsing errors.

In this example, for example, define and use input parameters, define and use templates:

#Define receive variables
module=$1
submodule=$2
page=$3

#Defining path variables
controller_path="./apps/controller"
controller_page_path=$controller_path/$module/$submodule/$page.js
view_path="./apps/view"
view_panel_path=$view_path/$module/$submodule/$page/Panel.js
view_index_path=$view_path/$module/$submodule/$page/index.vue
Copy the code

3. The shell passes parameters

When executing a shell script, you can pass parameters to the script in the format of N. N. N. 1 is the first argument to execute the script, 2 is the second argument to execute the script, and so on… 2 is the second argument to execute the script, and so on… 2 is the second argument to execute the script, and so on… 0 is the name of the execution file (including the file path)

In addition, $# is the number of arguments passed to the script.

For example, the script file is as follows

#! /bin/bash

echo "filename: $0";
echo "total params: $#"
echo "first params: $1";
echo "second params: $2";
echo "third params: $3";
Copy the code

Results after operation:

In this case, parameters and the total number of parameters are used to accept user input

#Define receive variables
module=$1
submodule=$2
page=$3

#Check whether the input parameter is less than 3
if [ $# -lt 3 ]
then
	echo "Usage: $0 <module> <submodule> <page>"
	exit 0
fi
Copy the code

4. The shell operator

Shell operators include relational operators, file test operators, and common arithmetic operators, Boolean operators, and logical operators, which are not covered in this discussion.

  • Relational operator

Relational operators only support numbers, not strings, unless the value of the string is a number.

The operator instructions
-eq Checks if two numbers are equal. Equality returns true
-ne Checks if two numbers are not equal. Returns true if they are not equal
-gt Checks if the number on the left is greater than the number on the right, and returns true if so
-lt Checks if the number on the left is less than the number on the right, and returns true if so
-ge Checks whether the number on the left is greater than or equal to the number on the right, and returns true if so
-le Checks whether the number on the left is less than or equal to the number on the right, and returns true if so

In this example, the -lt command is used to check whether the number of parameters entered by the user is sufficient to process.

#Check whether the input parameter is less than 3
if [ $# -lt 3 ]
then
	echo "Usage: $0 <module> <submodule> <page>"
	exit 0
fi
Copy the code
  • File test operator

The file test operator is used to detect various attributes of a file

The operator instructions
-d file Checks if the file is a directory, and returns true if so
-r file Checks whether the file is readable, and returns true if so.
-w file Checks if the file is writable, and returns true if it is.
-s file Checks if the file is empty (file size greater than 0), returns true if it is not empty.
-e file Checks whether files (including directories) exist and returns true if so.

Wait, the table only lists part of the operators.

In this example, use -e file to check whether the target file to be created exists

#Check whether the target file exists
if [ -e $controller_page_path ]
then
	echo "Error: $controller_page_path exists"
	exit 1
elif [ -e $view_panel_path ]
then
	echo "Error: $view_pannel_path exists"
	exit 1
elif [ -e $view_index_path ]
then
	echo "Error: $view_index_path exists"
	exit 1
fi
Copy the code

5. The shell of the echo command

The shell echo command is used to output strings. Can be used to output ordinary strings, variables, etc.

In this case, the output variable prompts an error when the object file exists

#Check whether the target file exists
if [ -e $controller_page_path ]
then
	echo "Error: $controller_page_path exists"
	exit 1
elif [ -e $view_panel_path ]
then
	echo "Error: $view_pannel_path exists"
	exit 1
elif [ -e $view_index_path ]
then
	echo "Error: $view_index_path exists"
	exit 1
fi
Copy the code

Echo also has some options: -e, etc

Echo -e: processes special characters. If special characters occur, they are not output as ordinary characters and need special processing. For example: \n wrap a line and move the cursor to the beginning of the line, \t insert TAB, etc

For example, run the following script

#! /bin/bash

echo "hello \n world";
echo -e "hello \n world";
echo "hello \t world";
echo -e "hello \t world";
Copy the code

Output result:

In this case, to output a template file with special characters.

#Special characters exist in the template and need to be processed by -e
touch $controller_page_path
echo -e "$controller_tpl" > $controller_page_path

touch $view_panel_path
echo -e "$view_panel_tpl" > $view_panel_path

touch $view_index_path
echo -e "$view_index_tpl" > $view_index_path
Copy the code

6. Shell process control

Note: the sh flow control cannot be null. If the else branch has no statement execution, do not write the else. The common ones are if else

If syntax format:

if condition
then
    command1 
    command2
    ...
    commandN 
fi
Copy the code

If else syntax:

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi
Copy the code

If else-if else syntax syntax:

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi
Copy the code

In this example, it is used to check whether the target file and target folder exist.

if [ $submodule ] then mkdir -p $controller_path/$module/$submodule mkdir -p $view_path/$moudle/$submodule fi if [ $page  ] then mkdir -p $view_path/$module/$submodule/$page fi if [ -e $controller_page_path ] then echo "Error: $controller_page_path exists" exit 1 elif [ -e $view_panel_path ] then echo "Error: $view_pannel_path exists" exit 1 elif [ -e $view_index_path ] then echo "Error: $view_index_path exists" exit 1 fiCopy the code

7. Shell input/output redirection

The command instructions note
command > file Redirect output to file. Execute command, then save the output to file, replacing the original content
command < file Redirect input to file.
command >> file Redirect output appending to file. Append to the end of the file

In this case, to output the template content to the target file.

touch $controller_page_path
echo -e "$controller_tpl" > $controller_page_path

touch $view_panel_path
echo -e "$view_panel_tpl" > $view_panel_path

touch $view_index_path
echo -e "$view_index_tpl" > $view_index_path
Copy the code

8. Sed command

Sed is a command used to select, replace, delete, and add data. Changes made by sed do not directly change the contents of the file. Instead, the changes are only displayed on the screen, unless the “-i” option is used to directly modify the file. The syntax is as follows:

Sed [option] '[action]' File nameCopy the code
  • Options:
Option of instructions For example,
-n The sed command normally outputs all data to the screen. With this option, only lines processed by the SED command will be output to the screen. Specify the second line of output input.txt

sed -n ‘2p’ student.txt
-e Allows multiple sed commands to edit input data
-f Specifies the name of the script file Read a SED operation from a SED script
-r Extended regular expressions are supported in SED.
-i Use sed to modify the read file directly, rather than screen output
  • action
Action name instructions For example,
s String substitution, the substitution of one string with another string. Format is “line range S /” old string/new string /g”
p Prints the specified line. Take a look at the second line of input.txt

sed ‘2p’ input.txt
d Delete deletes the specified row. Delete the data in rows 2 through 4

Sed ‘2, 4 d’ input. TXT
c \ Line replacement: Replace the original data line with the string following C. When replacing multiple lines, except for the last line, use “” at the end of each line to indicate that the data is not finished.

In this case, it is used to add the permissions for the new page to the modeEngine file.

#Added permission to the modeEngine filesed -i "s/\([[:space:]]*\)default:/\1\n\1case \'$module.$submodule.$page\':\n\1 import(\/\* webpackChunkName: \"$submodule.$page\" \*\/ '.\/controller\/$module\/$submodule\/$page.js').\n\1 then(function () {\n\1 openMode(module, newTab, params); \n\1 }); \n\1 break; \n\1 \n\1default:/" ./apps/modeEngine.jsCopy the code

9. The mkdir command

Mkdir Creates the specified directory name. The syntax is

mkdir [OPTION]... DIRECTORY...
Copy the code

options

Option of instructions
-m Set access permissions for the new directory
-p It can be a path name. If some directories in a path do not exist, the system automatically creates the directories that do not exist. That is, multiple directories can be created at a time.
-v Prints information for each directory created.
-help Display help information

In this case, to create a destination folder.

mkdir -p $controller_path/$module
mkdir -p $view_path/$module

if [ $submodule ]
then
	mkdir -p $controller_path/$module/$submodule
	mkdir -p $view_path/$moudle/$submodule
fi

if [ $page ]
then
	mkdir -p $view_path/$module/$submodule/$page
fi
Copy the code

10. Touch command

The touch command is mainly used to modify the timestamp of a file or create a new file that does not exist. Grammar:

touch [OPTION]... FILE...
Copy the code

options

Option of instructions
-a Change the read time record of the file
-m Change the modification time record of the file

, etc.

In this case, it is used to create the object file.

touch $controller_page_path
echo -e "$controller_tpl" > $controller_page_path

touch $view_panel_path
echo -e "$view_panel_tpl" > $view_panel_path

touch $view_index_path
echo -e "$view_index_tpl" > $view_index_path
Copy the code

11. The exit command

Using the exit command, you can exit the current Shell process and return an exit status. The exit command can take an integer value as an argument, representing the exit status. If not specified, the default status value is 0.

Vi. Shell implementation cases

The following projects have the same project background and process as the Node.js project:

#! /bin/bash

#Directions for use
#Git bash execution./auto_create_dir.sh + module name + sub-module name + page name (all mandatory)
#Automatically adds Controller, View Panel and Index, and modeEngine permissions

#Define receive variables
module=$1
submodule=$2
page=$3

#Defining path variables
controller_path="./apps/controller"
controller_page_path=$controller_path/$module/$submodule/$page.js
view_path="./apps/view"
view_panel_path=$view_path/$module/$submodule/$page/Panel.js
view_index_path=$view_path/$module/$submodule/$page/index.vue

#Define the templateheader_info="/** * @Author: $USER || $USERNAME || `git config user.name` * @Date: $(date "+%Y-%m-%d %H:%M:%S") * @Description: $page */ " controller_tpl="$header_info import 'components/mgr/AbstractMgr'; import 'view/$module/$submodule/$page/Panel'; Ext.define('app.controller.$module.$submodule.$page', { extend: 'app.components.mgr.AbstractMgr', title: _('$page'), views: ['$module.$submodule.$page.Panel'] }); " view_panel_tpl="$header_info import View from './index'; Ext.define('app.view.$module.$submodule.$page.Panel', { extend: 'Ext.panel.Panel', alias: 'widget.$module.$submodule.$page', layout: _('fit'), title: _('$page'), initComponent () { this.createItems(); this.callParent(arguments); }, createItems () { this.items = [ { itemId: 'vueComponent', xtype: 'box', vueCmp: View, enableVue: true } ]; }}); " view_index_tpl="<template> <div class=\"demo\">$page</div> </template> <script lang=\"ts\">
$header_infoimport {Component, Mixins, Watch, Prop} from 'vue-property-decorator'; @Component({ components: {}, mixins: [] }) export default class $page extends Mixins() { @Prop({ default: false }) disabled! : boolean; Private List = []; @Watch(\"list\", { deep: true }) handleListChange() {} mounted () {} listChange () {} } </script> <style lang="less" scoped> </style> " if [ $# -lt 3 ] then echo "Usage: $0 <module> <submodule> <page>" exit 0 fi mkdir -p $controller_path/$module mkdir -p $view_path/$module if [ $submodule ] then mkdir -p $controller_path/$module/$submodule mkdir -p $view_path/$moudle/$submodule fi if [ $page ] then mkdir -p  $view_path/$module/$submodule/$page fi if [ -e $controller_page_path ] then echo "Error: $controller_page_path exists" exit 1 elif [ -e $view_panel_path ] then echo "Error: $view_pannel_path exists" exit 1 elif [ -e $view_index_path ] then echo "Error: $view_index_path exists" exit 1 fi touch $controller_page_path echo -e "$controller_tpl" > $controller_page_path touch $view_panel_path echo -e "$view_panel_tpl" > $view_panel_path touch $view_index_path echo -e "$view_index_tpl" > $view_index_path
#Added permission to the modeEngine filesed -i "s/\([[:space:]]*\)default:/\1\n\1case \'$module.$submodule.$page\':\n\1 import(\/\* webpackChunkName: \"$submodule.$page\" \*\/ '.\/controller\/$module\/$submodule\/$page.js').\n\1 then(function () {\n\1 openMode(module, newTab, params); \n\1 }); \n\1 break; \n\1 \n\1default:/" ./apps/modeEngine.js exit 0Copy the code

Seven, reference

  1. The underlying principle of Node.js juejin.cn/post/700850…
  2. Node.js Chinese website nodejs.cn/
  3. Novice tutorial www.runoob.com/nodejs/node…
  4. Novice tutorial www.runoob.com/linux/linux…
  5. Shell learning tutorial blog.csdn.net/w918589859/…
  6. Linux shell -mkdir and touch command details blog.csdn.net/web_go_run/…