Yeoman, or Yo for short, is a great tool to learn from for most front-end teams, providing a proven way to develop, distribute, and use a project scaffolding, speed up project launches, and reuse project structures for front-end projects.
This article takes generator-iView-admin as an example to briefly explain the development process of the scaffolding, namely generator.
To prepare
To develop the Yeoman template, you need to install Yo:
npm i -g yo
Copy the code
Yo has carefully prepared the scaffolding generator for our scaffolding project:
npm i -g generator-generator
Copy the code
After installation, go to the development directory and run:
yo generator
Copy the code
The project structure
After the preceding command is executed, the following files are generated:
├─.yo-rc.json ├─ Package. json ├── app │ ├─ templates │ ├ myFile.txt │ ├─ index.jsCopy the code
Among them
.yo-rc.json
It is used for storage project configuration. It is not requiredpackage.json
NPM project information file, focusing on the author and version fieldsgenerators
The directory is the project template codegenerators/templates
Used to store project template filesgenerators/app/index.js
Defines the code for the project scaffolding
The development of
Each generator inherits the Yeoman-Generator class, the generators/app/index.js file described above. This class has several important lifecycle nodes:
initializing
– Initialization method, which is used to obtain project status and configurationprompting
– callinquireMethod to get user inputconfiguring
– Save the configuration and create.editorconfig
And other documentswriting
– Perform file write operations, that is, write project files to the file systeminstall
– This parameter is required to perform installation operationsthis.installDependencies
methodsend
– Last execution, can clear temporary files, etc
All of the above methods support returning a Promise to implement asynchronous operations, and only perform the next step if the returned Promise instance resolve is returned.
Step 1. Obtain the user configuration
First, we need to ask the user configuration in the Only Insurgent category (the full example is here) :
prompting() {
// Have Yeoman greet the user.
this.log(yosay('Welcome to the divine ' + chalk.red('generator-iview-admin') + ' generator! '));
const prompts = [{
type: 'input'.name: 'name'.message: 'Your project name'.default: this.appname
}, {
type: 'confirm'.name: 'lint'.message: 'Use ESLint to lint your code? '
}, {
name: 'lintStyle'.type: 'list'.message: 'Pick an ESLint preset',
when(answers) {
return answers.lint;
},
choices: [{
name: 'Airbnb (https://github.com/airbnb/javascript)'.value: 'airbnb'.short: 'Airbnb'
}, {
name: 'Standard (https://github.com/feross/standard)'.value: 'standard'.short: 'Standard'}}]];return this.prompt(prompts).then((props) = > {
// To access props later use this.props.someAnswer;
this.props = props;
});
}
Copy the code
Here, you configure the results entered by the user into the this.props object for subsequent access.
Step 2. Define the template
At the heart of Yo, which is essentially modifying template files on demand, there are three general methods:
- For simple objects such as JSON, you can use initPackage. That is, read templates, modify objects according to configurations, and write files
- For complex files, you can write them using the template (EJS) engine provided by Yo.
- Modifying files using the AST tree You can parse the syntax tree to deeply understand the template content, which is generally used to modify existing files. You are advised to use Esprima and Cheerio to parse AST.
Using ejS mode as an example, write a template (full example here):
The < %if(vueFile==='standalone') {% >// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.The < %} % >.../* eslint-disable no-new */
new Vue({
el: '#app',
router,<% if(vueFile==='runtime'){ %>
render: h= > h(App)<% } else if(vueFile==='standalone'){ %>
template: '<App/>'.components: { App }<% } %>
});
Copy the code
Step 3. Write as required
Once you get the configuration, you can start writing the template to hard disk (full example here) :
writing() {
this.initPackage();
this.renderTplFile();
}
initPackage() {
let pkg = this.fs.readJSON(this.templatePath('package.json'), {});
const {
props
} = this;
pkg = _.merge(pkg, {
name: props.name,
description: props.description }); . this.fs.writeJSON(this.destinationPath('package.json'), pkg);
}
renderTplFile() {
let target = [
...
'src/components/Hello.vue',];if (this.props.unitTest) {
target = target.concat([
...
'build/webpack.test.conf.js']); }... _.forEach(target, (file) => {this.fs.copyTpl(
this.templatePath(file),
this.destinationPath(file),
this.props
);
});
}
Copy the code
Yo provides the mem-Fs-Editor instance interface, which contains a series of FS tools:
this.fs.read
– Read filesthis.fs.readJSON
– Read files in JSON modethis.fs.write
– write filesthis.fs.writeJson
– Write files in JSON modethis.fs.append
– Appends the content to a filethis.fs.extendJSON
– Extends the content of the JSON filethis.fs.delete
– Delete files
In addition, there are a series of road and template interface:
this.fs.copyTpl
– Copies the template file, parses the template content according to parameters, and writes the template content to the target filethis.templatePath
– Returns the template file path, as described abovegenerator/app/templates
File path inthis.destinationPath
– Returns the target file path, that is, the path where the yo command is executed to generate the template filethis.registerTransformStream
– Life hook interface for converting file contents, compatiblegulp
The plug-in
At this point, we know all the interfaces we need to develop a Yo template.
Adding a subtemplate
Yo allows you to add any number of child templates by executing:
yo generator:subgenerator [name]
Copy the code
Take Yo Generator: Subgenerator test as an example. The following files are generated:
└ ── generators │ ├─ app │ ├─test│ ├─ Templates │ ├─ ├.txt │ ├─ index.jsCopy the code
Templates, index.js files do the same and can be developed directly.
A test run
You can add a project to the local Generator library by:
npm link
Copy the code
After that, you can execute the following command to generate the scaffolding:
yo [your template name]
Copy the code
release
After the template is developed, run the following commands to publish the template:
npm publish
Copy the code
Note:
- If NPM is not logged in, run this command
npm adduser
Operation Login- Publishing NPM packages must be used
https://registry.npmjs.org/
Source, remember to switch.