写一个umi插件 自动生成代码 解放cv的双手

引言

最近在写一个中台项目,使用的reactumi框架。
各种增删改查。基本是列表页 新建页 详情页这种页面
为了避免不必要的简单重复(主要是想偷懒) 于是想去实现自己的一个代码生成器

探索

首先,在官网上看到了官方写的一个生成器

再去源码里扒一扒 找到关键所在

简而言之,就是利用插件的api注册了一个生成model的指令,生成器指向目录里的model.js

代码如下

import { join } from 'path';
import assert from 'assert';

export default api => {
  const { paths, config } = api;
  const absTemplatePath = join(__dirname, '../template/generators');

  return class Generator extends api.Generator {
    writing() {
       ...
       // 判断目录名是models还是model
      const models = config.singular ? 'model' : 'models';
      const name = this.args[0].toString();
      ...
     // 将模板目录下里的model代码 拷贝到项目的model目录下 并命名为指令输入的文件名
      this.fs.copyTpl(
        join(absTemplatePath, 'model.js'),
        join(paths.absSrcPath, models, `${name}.js`),
        {
          name,
        },
      );
    }
  };
};
../template/generators/model.js

export default {
  state: '<%= name %>',
  subscriptions: {
    setup({ dispatch, history }) {
    },
  },
  reducers: {
    update(state) {
      return `${state}_<%= name %>`;
    },
  },
  effects: {
    *fetch({ type, payload }, { put, call, select }) {
    },
  },
}

model是一个常规的dvamodel
里面的<%= name %>ejs语法,对应着copyTpl方法的第三个参数中的name
模板js里的这个占位会被参数name替换

因为我们项目中习惯将model写到模块文件夹下,而且model里的代码有些我们的自己的书写
所以需要自定义一个生成方法了。

上手

以下是我写的一个生成规则

import { join } from 'path';
const fs=require('fs');
export default api => {
  const  {paths} = api;
  const configPath=join(paths.absSrcPath,'generatorConfig.js');
  const absTemplatePath = join(__dirname, '../template/generators');
  return class Generator extends api.Generator {
    writing() {
      const name = this.args[0].toString();
      // assert(!name.includes('/'), `model name should not contains /, bug got ${name}`);
      const type =this.args[1]&& this.args[1].toString();
     // type即为命令后跟的参数
      switch (type) {
        case 'list':
          if(!fs.existsSync(configPath)) {
            api.log.error('新建列表模板缺少generatorConfig.js')
            return
          }
          const genConfig=require(configPath);
          this.fs.copyTpl(join(absTemplatePath, 'list.js'),join(paths.absSrcPath, `pages/${name}/${type}`, `index.js`), {
            name,
            queryFormItems:genConfig[name]['queryFormItems'],
            columns:genConfig[name]['columns']
          });
      }
      this.fs.copyTpl(join(absTemplatePath, 'model.js'), join(paths.absSrcPath, `pages/${name}`, `model.js`), {
        name
      });
      this.fs.copyTpl(join(absTemplatePath, 'index.less'), join(paths.absSrcPath, `pages/${name}`, `index.less`), {
        name
      });
      this.fs.copyTpl(join(absTemplatePath, 'service.js'), join(paths.absSrcPath, `pages/${name}`, `service.js`), {
        name
      });
    }
  };
};

添加了如下功能

  • 结合项目中的目录结构约定进行目录生成(比如我们约定用service来进行接口方法管理)
  • 增加在命令后面加不同参数 生成不同的特征模块(比如列表 详情)
  • 增加了配置项 可以在node环境下去读取配置 再生成到代码里去(比如 antd的列表的columns

再仿照umi-dva-plugin的流程进行命令注册插件导出

import { join } from 'path';
export default(api, opts = {})=> {
  api.registerGenerator('dva:newPage', {
    Generator: require('./model').default(api),
    resolved: join(__dirname, './model'),
  });
}

遇到问题

在探索和上手遇到挺多问题,总结如下
1.阅读源码 加以甄别 ,因为umi-dva-plugin的代码贼多,模板功能只是其中的非核心功能,所以也是看了好几遍 发现这个功能其实和其他代码并不存在耦合 可以单独提出来
2.探索模板语法 一开始不知道是ejs 找了下copyTpl方法

然后就恍然大悟,怪不得看起来那么熟悉,顺便学了一下ejs模板<%= %><%- %>的区别
3.兼容性问题 遇到的一个贼奇怪的问题 node环境兼容的问题
一开始不知道 用babel转成es5了 一直报错class constructor Generator cannot be invoked without ‘new
看上去就是个兼容问题 然后用web版的babel转换器 关闭preset es2015 调整node版本6.4主要是把对象的解构赋值要转换掉 不然依赖的三方Generator可能不认

总结

现在看来其实写这个插件其实并不难,但是在当时很多知识都不了解的情况下去看,确实还是有些许棘手,了解用法和原理比较有挑战,毕竟不是自己写的代码,所以还是要加强代码方便的阅读。

项目链接

戳我查看

原文地址:https://www.cnblogs.com/amigod/p/umi-plugin-a.html

时间: 2024-10-01 04:29:34

写一个umi插件 自动生成代码 解放cv的双手的相关文章

IEDA 使用mybatis-generator插件自动生成代码及遇到的问题

一.pom配置 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <!--配置文件的位置--> <configurationFile>src/ma

写一个TT模板自动生成spring.net下面的配置文件。

这个是目标. 然后想着就怎么开始 1.

maven插件mybatis-generator自动生成代码

在开发中ssm框架用的十分广泛.mybatis最为持久层框架,根据xml.或者注解映射数据.自己可以控制sql,灵活简单操作数据库.但是,所有的sql文件都是有自己编写,不仅繁琐,而且很耗时,在开发中,速度.效率很重要.所以很多基础sql是有规律可循,可以根据数据库字段自动生成的.下面就进入今天的主题,通过maven插件mybatis-generator自动生成代码. 1.环境配置,创建maven项目,在pom.xml添加插件配置. <build> <finalName>zsxt&

Cordova webapp实战开发:(6)如何写一个iOS下自动更新的插件?

上一篇我们学习了如何写一个Andorid下自动更新的插件,我想还有一部分看本系列blog的开发人员希望学习在iOS下如何做插件的吧,那么今天你就可以来看看这篇文字了. 本次练习你能学到的 学习如何获取iOS当前版本号 学习iOS下插件类的编写 学习iOS下插件的配置 学习iOS下插件的调用 主要内容 APP中[检查更新]显示当前版本号 插件类的编写 在上一篇介绍Andorid插件时我们贴出了很多源码,这里也直接贴出代码,首先是iOS下插件的代码. 我们在Plugins下新建两个文件,一个头文件

IDEA——mybatis-generator插件自动生成实体代码(Maven)

利用MyBatis生成器自动生成实体类.DAO接口和Mapping映射文件.  mysql-connector-java-5.1.6-bin.jar mysql驱动包  mybatis-generator-core-1.3.5.jar 自动生成器包 maven 配置mybatis-generator插件 一.pom.xml 两处配置 (1) (2) 二.创建 generatorConfig.xml 配置如下: 1 <?xml version="1.0" encoding=&quo

SpringBoot 添加mybatis generator 自动生成代码插件

自动生成数据层代码,提高开发效率 1.pom添加插件,并指定配置文件路径 <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <

mybatis分页插件,自动生成代码插件

1.分页插件 在上一篇介绍拦截器中尝试了封装分页插件,其实有更好的mybatis分页插件PageHelper,具体用法: 1.导包 2.注册拦截器 3.写mapper 4.调用 结果如下: 结果pageInfo数据解析: 还有很多的属性,具体可以自己测试 2.自动生成代码 自动生成代码可以帮助我们生成实体类,mapper映射一级dao接口文件,减少代码量,使用方法: 1.导包: 2.编辑配置文件,配置文件的位置与上面配置中的位置要一致: <?xml version="1.0" e

用maven插件自动生成mybatis代码(转载http://blog.csdn.net/yinkgh/article/details/52512983)

1.在springmvc+mybatis项目的pom.xml文件中加如下内容,添加之后,maven会自动下载相关jar包,时间较长,需要耐心等待~~ <build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>

Java进阶之 如何自动生成代码

一.前言:为什么要有代码的自动生成? 对于这个问题 最简洁直接的回答就是:代替手动编写代码.提高工作效率. 什么样的场景和代码适合用自动生成这种方式呢? 做过Java服务端的朋友一定都知道代码中我们需要编写与数据库表映射的Java实体类(Entity).需要编写与实体对应的DAO类(XxDao.java类中有包含对应实体的增.删.改.查基本操作).在这些实体类中通常都是一些属性方法以及属性对应的get/set方法.而实体对应的DAO类中也基本会包含有增.删.改.查这些与数据库操作相关的方法.在编