持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
上一篇:React项目优化(4)-使用错误边界(ErrorBoundry)解决白屏问题
1、PlopJs是什么 ?
简而言之:PlopJs是一个根据模板生成代码的工具。只需要安装一个依赖包,写一个配置文件。就可以执行 plop 命令生成代码。
2、我为什么要使用PlopJs
-
项目特点
项目的功能能节点多,其中每一个功能节点(模块)都是一个独立的单页面应用,这些单页面应用彼此独立,但是目录结构相同,除了具体的业务逻辑不同以外,其他的诸如:
service.js、model.js、app.js、api.http等文件内容基本一致。 即使不一致,也有很强的规律性。
-
方便管理
每个开发的操作习惯不一致。对代码的理解程度不一样,解决思路不一致,导致原本相同的事情,会出现不同的版本,甚至导致不同的BUG出现。或许开发者A已经解决的问题,开发者B会重新处理一次。
如果能够直接通过脚手架生成基础性的代码。那些规律性的,可预见的基础问题,在代码生成时,就一次性解决的,这是不是很哇塞。 -
开发效率
开发中,机械性的、重复性、复制、粘贴的体力劳动比较多,同时开发效率有比较低。所以,有必要通过
plopJs解放劳动力。所以说:使用
PlopJs生成代码,可以提高开发效率,统一代码风格,规避一些不必要的错误。
3、项目实战
安装依赖
可以全局安装,也可以在项目中安装
npm install -g plop // 全局安装
示例一:牛刀小试,生成一个组件模板
- 在项目的根目录下新建文件夹命名为
plop-template - 在
plop-template新建Component文件夹 - 在
Component文件夹下新建两个文件plop.js和index.hbs - 其中
plop.js是用于配置交互收集处理的模块
代码如下:
module.exports = {
description: "生成React组件",
prompts: [
{
type: "input", // 交互类型
name: "name", //参数名称
message: "请输入组件名称:", // 交互提示
},
],
actions: (data) => {
const name = "{{ name }}"; // 这个变量来之控制台输入,在模板文件中可以使用。
return [
{
type: "add", // 新增文件
path: `ucf-common/src/components/${name}/index.js`, // 生成文件的路径
templateFile: "plop-template/component/index.hbs", // 模板文件的路径
},
{
type: "add",
path: `ucf-common/src/components/${name}/index.less`,
templateFile: "plop-template/component/style.hbs",
},
];
},
};
- 其中
index.hbs是模板文件,生成的文件是啥样,由它决定。
模板文件是 HandleBars文件。了解更多
简单说: 把你希望生成的文件的后缀名改成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}};
配置文件编写
在项目的根目录下新建plopfile.js配置文件
使用plop.setGenerator这个方法将模板文件注入,再讲这个模块导出即可。
代码示例如下:
// 1. 引入写好的组件配置
const compGenerator = require("./plop-template/component/prop");
module.exports = function (plop) {
// 使用生成器,注入配置[component为名称]
plop.setGenerator("component", compGenerator); // 生成React组件文件模板
}
生成模板操作
打开控制台运行plop命令,根据提示输入相应内容即可
示例二:大显身手,生成项目文件夹
基本步骤与生成一个组件一致,但是有如下不同。
- 生成的是一组有不同层级的文件,而非一个文件。
- 生成的项目文件夹之前前需要输入一系列的提示项,传入较多的变量。
- 命令行输入时,增加提示语,默认值,长度及合法性校验方法。
- 处理输入字符外,提供了类似下拉选的单选模式。
配置文件代码示例:
module.exports = {
description: "生成节点模板",
prompts: [
{
type: "input",
name: "nodeName",
message: "请输入文件夹名称[eg:fls-contract]",
default: "fls-demo",
validate: function (val) {
if (/.+/.test(val)) {
if (val.length < 6 || val.length > 20) {
return "文件夹名称长度[6-20]的小写英文单词";
}
return true;
} else {
return "文件夹名称不能为空!";
}
},
},
{
type: "input", // 交互类型,字符输入
name: "funCode", //参数名称
message: "请输入节点编码[eg:fls0001]", // 交互提示
default: "fls0000",
validate: function (val) {
if (!!val && val.length == 7) {
return true;
} else {
return "请保持节点编码长度为7";
}
},
},
{
type: "list", // 交互类型: 上下键选择
name: "server", //参数名称
message: "请选择后端服务:", // 交互提示
choices: [
"imfbp-fls-before-web",
"imfbp-fls-after-web",
"imfbp-crm-web",
"imfbp-invoice-web",
],
default: "imfbp-fls-before-web",
},
],
actions: (data) => {
const nodeName = "{{ nodeName }}";
return [
{
type: "addMany", // 增加多个文件
base: "plop-template/layout/", // 生成,目标路径会去掉这写路径
stripExtensions: true,
destination: `ucf-apps/${nodeName}/`, // 目标路径
templateFiles: "plop-template/layout/src/**/**", // 配置的模板文件路径.
},
];
},
};
模板文件夹目录:
如果需要一些特殊的逻辑处理,可以通过plop.setHelper校验方法:
// 方法:用于根据输入的前缀获取请求数据的常量
plop.setHelper("getConstPrefix", function (text) {
let retText = "";
switch (text) {
case "imfbp-fls-before-web":
retText = "GROBAL_FLS_BEFORE_HTTP_CTX";
break;
...
default:
retText = "模板文件未配置";
break;
}
return retText;
});
// 方法:用于在模板中输出双花括号格式
plop.setHelper("bracket", function (num, options = num) {
const i = Number.isInteger(num) ? num : 1;
const open = "{".repeat(i);
const close = "}".repeat(i);
return `${open}${options.fn(this)}${close}`;
});
生成代码操作
总结
使用 PlopJs 生成文件的过程不复杂,如果在使用中需要问题,查看官方的文档即可:
PlopJs官方文档
HandleBar官网
4、其他问题
使用plopJs可以根据模板生成代码。但是随之而来的是另一个问题,由于我们项目中业务逻辑比较复杂,尤其是其中的表单和表格,一个表单中表单项动辄几十个。每一手写或复制也是不小的工作量, 如果能够根据后端的字段通过某种方式直接生成表单。那将是开发效率的又一次提升。
具体如何实现? 下一篇文章见!