Yeoman学习笔记:常用 cheatsheet
yeoman 常用操作记录,如何编写一个项目中使用的脚手架,安装更新使用
🕐
安装与更新
npm i -g yo
npm update -g yo示例 .yo-rc 文件
{
"@jswork/generator-react-app": {
"component": {
"prefix": "",
"components_dir": "src/components",
"component_type": "functional",
"export_type": "const",
"file_type": "tsx"
},
"hook": {
"prefix": "use-",
"components_dir": "src/hooks",
"export_type": "const",
"file_type": "tsx"
}
}
}常用操作
| 名称 | 命令 | 备注 |
|---|---|---|
templates目录里的所有文件 | | 文件copy到目标位置 |
生成相关的 prompts | | 参考 repositry |
取得 option 配置 | | this._config 是 内部变量,不要在项目中使用 |
| 设置/获取 option | | yo @jswork/tailwind --styles="./styles" yo @jswork/tailwind --styles ./styles |
| copy单个文件 | | |
| copy并填props | | |
| copy 并带 ctx | | 可以用来处理各种转换场景 |
| copy目录 | | |
| copy 并且 rename | | |
| 对package.json的操作 | |
常见的 cli 交互类型
| 类型 | 代码 | 备注 |
|---|---|---|
| input | | |
| input(store) | | |
| confirm | | Yes/No 类型 |
| checkbox | |
Copy所有 templates 中的文件
- 没有任何的逻辑
- 几乎没有
prompts
'use strict';
const Generator = require('yeoman-generator');
const globby = require('globby');
module.exports = class extends Generator {
prompting() {
const prompts = [];
return this.prompt(prompts).then((props) => {
this.props = props;
});
}
writing() {
this.fs.copyTpl(
globby.sync(this.templatePath('**'), { dot: true }),
this.destinationPath(),
this.props
);
}
};Case 在 yeoman 中使用 JS 函数
- 实现转换功能:
<%- ctx.classify(model_name) %> - 实现单复数功能:
<%- ctx.pluralize(model_name) %>
# from orator import Model
from .abstract_model import AbstractModel
class <%- ctx.classify(model_name) %>(AbstractModel):
__table__ = '<%- ctx.pluralize(model_name) %>'
pass"use strict";
const Generator = require("yeoman-generator");
const globby = require("globby");
const yoHelper = require("@jswork/yeoman-generator-helper");
module.exports = class extends Generator {
async prompting() {
const prompts = [
{
type: "input",
name: "model_name",
message: "Your model_name?",
validate: Boolean
}
];
this.props = await this.prompt(prompts);
}
writing() {
const { model_name } = this.props;
const dirs = globby.sync("**/models", { onlyDirectories: true });
const target = dirs.find(item => item.endsWith("models"));
this.fs.copyTpl(
this.templatePath("model.py"),
this.destinationPath(`${target}/${model_name}.py`),
{ ...this.props, ctx: yoHelper.ctx }
);
}
};增加 package.json 里的内容
'use strict';
const Generator = require('yeoman-generator');
const globby = require('globby');
// yo @jswork/dotfiles:prettier --ideable
module.exports = class extends Generator {
writing() {
const pattern = this.options.ideable ? '**' : '.pre*';
const opts = { dot: true };
this.fs.copyTpl(
globby.sync(this.templatePath(pattern), opts),
this.destinationPath(),
this.props
);
}
installDeps() {
const pkgJson = {
devDependencies: {
prettier: '^2.5.1'
}
};
this.fs.extendJSON(this.destinationPath('package.json'), pkgJson);
}
};重命名问题
- 已经不可用的方式(
queueTransformStream): - 推荐的方式(
this.fs.copyTpl第5个参数):
几个基本的阶段
initializing- Your initialization methods (checking current project state, getting configs, etc)prompting- Where you prompt users for options (where you’d callthis.prompt())configuring- Saving configurations and configure the project (creating.editorconfigfiles and other metadata files)default- If the method name doesn’t match a priority, it will be pushed to this group.writing- Where you write the generator specific files (routes, controllers, etc)conflicts- Where conflicts are handled (used internally)install- Where installations are run (npm, bower)end- Called last, cleanup, say good bye, etc