使用场景
最近进行代码评审发现项目中有很多无用代码且每个菜单中的无用代码都非常类似,经过排查发现是因为在创建新需求时前端开发人员都是直接将写好的需求复制从而导致无用代码的产生,所以在此场景下决定使用plop进行新需求模版的新建,避免无用代码及删除无用代码时间成本的产生。
plop简介
简单来说,plop就是一个微型的生成器框架,用于生成符合团队规范的模版文件。它提供了一种快速生成代码或其他文本文件的便捷方式,同时又保持了很小的体积。
安装
1. 局部安装
$ npm install --save-dev plop
2. 全局安装(可选,但为了避免权限问题引起的错误,推荐安装)
$ npm install -g plop
3. 在项目根文件夹创建 plopfile.js
4. 在项目根文件夹创建plop-template
在此目录下生成plop文件及文件模版,一个 plop 文件就是一个简单的 node 模块,它导出一个函数,这个函数接收一个 plop 对象作为第一个参数。
一个 plop 对象暴露一个包含 setGenerator(name, config) 函数的 plop api。setGenerator 用于创建一个生成器(generator)。当 plop 在当前文件夹或子文件夹的终端中运行时,这些 generator 将会以列表的形式被展示在终端中。
plopfile.js
// 1. 引入写好的组件配置
const compGenerator = require('./plop-template/plop');
module.exports = function (plop) {
// 使用生成器,注入配置[component为名称]
plop.setGenerator('component', compGenerator); // 生成React组件文件模板
};
plop.js
checkFileName是用来检验组件名称是否重复,如果重复则进行相应提示。
const checkFileName = require('../utils/checkFileName');
module.exports = {
description: '生成React组件',
prompts: [
{
type: 'input', // 交互类型
name: 'name', //参数名称
message: '请输入组件名称:', // 交互提示
validate: (value) => {
if (/.+/.test(value)) {
return checkFileName(value)
? '已经存在相同的容器名或者组件名'
: true;
}
return '容器名必填';
},
},
],
actions: (data) => {
const name = '{{ name }}'; // 这个变量来之控制台输入,在模板文件中可以使用。
return [
{
type: 'add', // 新增文件
path: `src/page/${name}/index.js`, // 生成文件的路径
templateFile: 'plop-template/index.hbs', // 模板文件的路径
},
{
type: 'add',
path: `src/page/${name}/model/modelB.ts`,
templateFile: 'plop-template/model.hbs',
},
{
type: 'add',
path: `src/page/${name}/handles/handlesB.ts`,
templateFile: 'plop-template/model.hbs',
},
{
type: 'add',
path: `src/page/${name}/service/service.ts`,
templateFile: 'plop-template/model.hbs',
},
];
},
};
index.hbs
.hbs是模版文件,生成文件的模版在改文件中进行配置。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Classnames from "classnames";
import { Button } from 'tinper-bee';
import './index.less'
import { Error } from "utils";
const propTypes = {
title: PropTypes.string,//
};
const defaultProps = {
title:"标题",
};
// 组件模板
class {{properCase name}} extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
// componentDidMount...
}
render() {
let {title}=this.props;
return (
<div className="{{dashCase name}}-wrap">
<span>Test</span>
<span>{{a}}</span>
</div>
)
}
}
{{properCase name}}.propTypes = propTypes;
{{properCase name}}.defaultProps = defaultProps;
export default {{properCase name}};Ï
checkFileName.js
校验文件名是否重复
const fs = require("fs");
const path = require("path");
const pageComponents = fs.readdirSync(
path.join(__dirname, "../src/page")
);
function componentExists(comp) {
return pageComponents.indexOf(comp) >= 0;
}
module.exports = componentExists;
最后
执行'plop'生成模版文件(这里只是进行一个简单的示例,如有其他配置需求可在plop.js中进行个性化配置。)