engineering
define
Front-end engineering refers to the means to improve efficiency and reduce costs through tools in accordance with certain standards and specifications.
All the means to improve efficiency, reduce costs, and ensure quality for the purpose of engineering
Main problem solved
- A weakness of traditional language or grammar
- Modularity/componentization cannot be used
- Repetitive mechanical work
- Uniform code style, quality assurance
- Rely on back-end service interface support
- Overall reliance on back-end projects
Engineering ≠ a tool
At this stage, some tools are so large, such as WebPack, that some novices mistakenly think that engineering means Webpack. As long as you use Webpack, you have engineering. In fact, this is not the case. Tools are not the core of engineering. The core of engineering is the overall planning or architecture of the project. Tools are only a means to implement this planning or architecture in the process.
Scaffolding tool
Summary of Scaffolding Tools
The essential role of scaffolding is to create the project infrastructure and provide project specifications and conventions.
Same convention:
- Same organizational structure
- Same development paradigm
- Same module dependencies
- Same tool configuration
- Same basic code
Commonly used scaffolding tools
React project –> create-React-app, vue project –>vue-cli, and Angular project –> Angular-CLI. Yeoman is a general-purpose project scaffolding tool that generates a project structure from a set of templates, which is flexible and easy to scale. Plop is used to create specific types of files during project development, such as files needed to create a component/module.
Yeoman
The basic use
Yonpm I yo –global install the corresponding generator, NPM I Generator-node –global Run generatoryo node sub Generator with yo to create a specific type of file based on an existing project, for example, yo node: CLI
Summary of usage Steps
- Know your needs
- Find the appropriate Generator
- The global scope installs the Generator found
- Run the corresponding Generator through yo
- Enter options interactively on the command line
- Generate the project structure you need
A custom Generator
The custom Generator builds its own scaffolding based on Yeoman. Create the Generator
A Generator is essentially an NPM module
Basic structure of Generator
The commandgenerator-<name>
The sample
// Create the generator-sample directory
mkdir generator-sample
cd generator-sample\
// Initialize package.json
npm init
// Install the Yeoman dependency
npm i yeoman-generator
Copy the code
Next go to the Generator -sample folder and create a generators/app/index.js file
// index.js
// This file serves as the core entry for the Generator
// We need to export a type inherited from Yeoman Generator
// As the Yeoman Generator works, it automatically calls some of the lifecycle methods we defined in this type
// In these methods, we can call some utility methods provided by the parent class to achieve some functions, such as file writing
const Generator = require('yeoman-generator')
// Export a type that inherits from the Generator
module.exports = class extends Generator {
writing () {
// Yeoman automatically calls this method during the file generation phase
// Here we try to write files to the project directory
this.fs.write(
// The absolute file path
this.destinationPath('temp.txt'),
Math.random().toString()
)
}
}
Copy the code
Then we link to the global scope via NPM link to make it a global module package, so that Yeoman can find the generator sample we wrote when he works. You can then run the generator with yo Sample to create a temp.txt.
- Create files from the template
In many cases, there are many files that need to be automatically created, and the contents of the files are relatively complex. In this case, you can use templates to create files. First create generators/app/templates/foo. TXT file
// This is a template file foo.txt
// Internally you can use EJS template tags to output data
// For example: <%= title %>
// Other EJS syntax is also supportedThe < %if(success) {%> hahaha <%}%>Copy the code
Once you have the template, you can write the file to the target directory as a template when the file is generated
// index.js
// This file serves as the core entry for the Generator
// We need to export a type inherited from Yeoman Generator
// As the Yeoman Generator works, it automatically calls some of the lifecycle methods we defined in this type
// In these methods, we can call some utility methods provided by the parent class to achieve some functions, such as file writing
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
writing () {
// Yeoman automatically calls this method during the file generation phase
// Write the file to the target directory in template mode
// Path of the template file
const tmpl = this.templatePath('foo.txt')
// Output the target path
const output = this.destinationPath('foo.txt')
// Template data context
const context = { title: 'Hello zce~'.success: false }
// Automatically map template files to the output directory
this.fs.copyTpl(tmpl, output, context)
}
}
Copy the code
- Receive user input data
// index.js
// This file serves as the core entry for the Generator
// We need to export a type inherited from Yeoman Generator
// As the Yeoman Generator works, it automatically calls some of the lifecycle methods we defined in this type
// In these methods, we can call some utility methods provided by the parent class to achieve some functions, such as file writing
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
prompting () {
// This method is automatically called by Yeoman when the user is asked
// In this method, you can invoke the prompt() method of the parent class to issue a command line query to the user
// Return a promise
return this.prompt([
{
type: 'input'.name: 'name'.message: 'Your project name'.default: this.appname // Appname is the name of the project build directory
}
])
.then(answers= > {
this.answers = answers
})
}
writing () {
// Yeoman automatically calls this method during the file generation phase
// Path of the template file
const tmpl = this.templatePath('bar.html')
// Output the target path
const output = this.destinationPath('bar.html')
// Template data context
const context = this.answers
this.fs.copyTpl(tmpl, output, context)
}
}
Copy the code
Vue Generator case
// Create a directory
mkdir generator-jc-vue
cd generator-jc-vue\
// Initialize package.json
npm init
// Install the Yeoman dependency
npm i yeoman-generator
Copy the code
Create a generator home directory file (generators/app/index.js)
Create a generators/app/templates directory, copy the structure of the project as a template, and change the project name to the template engine syntax<%= name %>
// index.js
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
prompting () {
return this.prompt([
{
type: 'input'.name: 'name'.message: 'Your project name'.default: this.appname
}
])
.then(answers= > {
this.answers = answers
})
}
writing () {
// Convert each file to the target path through the template
const templates = [
'.browserslistrc'.'.editorconfig'.'.env.development'.'.env.production'.'.eslintrc.js'.'.gitignore'.'babel.config.js'.'package.json'.'postcss.config.js'.'README.md'.'public/favicon.ico'.'public/index.html'.'src/App.vue'.'src/main.js'.'src/router.js'.'src/assets/logo.png'.'src/components/HelloWorld.vue'.'src/store/actions.js'.'src/store/getters.js'.'src/store/index.js'.'src/store/mutations.js'.'src/store/state.js'.'src/utils/request.js'.'src/views/About.vue'.'src/views/Home.vue'
]
// Iterate to generate the corresponding object file
templates.forEach(item= > {
// item => each file path
this.fs.copyTpl(
this.templatePath(item),
this.destinationPath(item),
this.answers
)
})
}
}
Copy the code
Generate the project with the yo jc-vue command
Release the Generator
Since a Generator is actually an NPM module, publishing a Generator is to publish an NPM module. We only need to publish the Generator module written by ourselves into a public module by using the NPM publish command.
Plop
Plop is a tool for creating specific types of files in a project. It is usually integrated into a project to automate the creation of files of the same type, not independently.
// Install dependencies
npm i plop --dev
Copy the code
Create a new plopfile.js file in the project root directory
// Plop entry file, need to export a function
// This function receives a plop object to create the generator task
module.exports = plop= > {
// setGenerator(generator name, generator configuration options)
plop.setGenerator('component', {
// Generator description
description: 'create a component'.// Command line problem
prompts: [{type: 'input'.name: 'name'.message: 'component name'.default: 'MyComponent'}].// The action that the generator performs after completing the command line problem
actions: [{type: 'add'.// represents adding files
path: 'src/components/{{name}}/{{name}}.js'.templateFile: 'plop-templates/component.hbs' // Template file
},
{
type: 'add'.// represents adding files
path: 'src/components/{{name}}/{{name}}.css'.templateFile: 'plop-templates/component.css.hbs'
},
{
type: 'add'.// represents adding files
path: 'src/components/{{name}}/{{name}}.test.js'.templateFile: 'plop-templates/component.test.hbs'})}}]Copy the code
/ / the plop
npm plop component
Copy the code
How scaffolding works
Most scaffolding works by asking you a set of pre-set questions when it is launched and using your answers in conjunction with the template file to generate a project structure.
mkdir sample-scaffolding
cd sample-scaffolding\
npm init
Copy the code
Add the bin field to the package.json file to specify the entry file for the CLI project
// package.json
{
"name": "sample-scaffolding"."version": "0.1.0 from"."main": "index.js"."bin": "cli.js"."author": "zce <[email protected]> (https://zce.me)"."license": "MIT"."dependencies": {
"ejs": "^ 2.6.2." "."inquirer": "^ 7.0.0." "}}Copy the code
Add the cli.js file
#! /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, so that this file can be used as a CLI entry
Chmod 755 cli.js
// The working process of scaffolding:
// 1. Ask the user interactive questions through the command line
// 2. Generate a file based on the answer results of the user
const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')
const ejs = require('ejs')
inquirer.prompt([
{
type: 'input'.name: 'name'.message: 'Project name? '
}
])
.then(anwsers= > {
// Generate a file based on the results of the user's answers
// The template directory
const tmplDir = path.join(__dirname, 'templates')
// The target directory
const destDir = process.cwd()
// Convert all files in the template to the target directory
fs.readdir(tmplDir, (err, files) = > {
if (err) throw err
files.forEach(file= > {
// Render the file through the template engine
ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) = > {
if (err) throw err
// Write the result to the destination file path
fs.writeFileSync(path.join(destDir, file), result)
})
})
})
})
Copy the code
Run NPM link to link this module to the global execution of sample-scaffolding to generate the file