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
目录里的所有文件const srcFiles = globby.sync(this.templatePath('**'), { dot: true });
const dstPath = this.destinationPath();
this.fs.copy(srcFiles, dstPath);
文件copy到目标位置 生成相关的 prompts
// es6
import genp from '@jswork/generator-prompts';
const prompts = genp(["scope", "registry", "project_name", "description"]);
// es5
const getp = require("@jswork/generator-prompts");
const prompts = getp(["scope", "registry", "project_name", "description"]);
参考 repositry 取得 option
配置 // 取得 hook 配置
this.config.get('hook');
// 取得所有的配置
this.config.getAll();
this._config
是 内部变量,不要在项目中使用设置/获取 option // 设置 option
this.argument("styles", { type: String, default: "./src/assets/styles" });
// 获取 option
const styles = this.options.styles;
yo @jswork/tailwind --styles="./styles" yo @jswork/tailwind --styles ./styles copy单个文件 this.fs.copy(
this.templatePath("tailwind.config.js"),
this.destinationPath(resolve("tailwind.config.js"))
);
copy并填props this.fs.copyTpl(
globby.sync(this.templatePath("**"), { dot: true }),
this.destinationPath(),
this.props
);
copy 并带 ctx // 可用用来处理 case 转换等场景
// import <%- ctx.camelize(project_name) %> from '@<%= scope %>/<%= project_name %>';
this.fs.copyTpl(
globby.sync(this.templatePath("**"), { dot: true }),
this.destinationPath(),
{ ...this.props, ctx: yoHelper.ctx }
);
可以用来处理各种转换场景 copy目录 this.fs.copy(
globby.sync(this.templatePath("tailwind/**"), { dot: true }),
this.destinationPath(this.options.styles)
);
copy 并且 rename const { project_name } = this.props;
const ctx = yoHelper.ctx;
this.fs.copyTpl(
globby.sync(this.templatePath("**"), { dot: true }),
this.destinationPath(),
{ ...this.props, ctx },
null,
{
processDestinationPath: (filePath) => {
return filePath.replace("jsw_nx", ctx.underscored(project_name));
},
}
);
对package.json的操作 const pkgJson = {
devDependencies: {
eslint: "^3.15.0"
},
dependencies: {
react: "^16.2.0"
}
};
// Extend or create package.json file in destination path
this.fs.extendJSON(this.destinationPath("package.json"), pkgJson);
常见的 cli
交互类型 类型 代码 备注 input {
type: 'input',
name: 'description',
message: 'Your description?',
validate: Boolean
}
input(store) {
type : 'input',
name : 'username',
message : 'What\'s your Github username',
store : true
}
confirm {
type: 'confirm',
name: 'cool',
message: 'Would you like to enable the Cool feature?'
}
Yes/No 类型 checkbox {
type: 'checkbox',
name: 'database',
message: 'Select Database support:',
choices: [
{
name: 'H2',
value: 'h2'
},
{
name: 'HSQLDB',
value: 'hsqldb'
}
]
}
Copy所有 templates
中的文件 '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 call this.prompt()
)configuring
- Saving configurations and configure the project (creating .editorconfig
files 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参考