29

硬核开源,使用 react-hooks 手写 ant-design-pro,搭配 node 完整api

 4 years ago
source link: https://juejin.im/post/5e313c35e51d453ce13d2455
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

硬核开源,使用 react-hooks 手写 ant-design-pro,搭配 node 完整api

最开始的时候,我需要一个 react 开发的 amdin 模版,在开源社区寻找了一边之后,比较中意 ant design proUI,当我一堆操作把 ant desgin pro 的代码拉下来研究之后,发现内容是在太多了,除了 reactredux 之外,还包含了 umidvaant-design/pro-layout 等其它东西,当这些概念和 ts 结合起来使用的时候,作为一个 react新手,我瞬间感觉无处下手,后面又仔细了阅读了权限设计、菜单栏渲染部分的代码,我得出结论, Ant Design Pro 足够优秀,但不适合我的需求场景。很遗憾,只能放弃使用

但是,Ant Design ProUI 最为好看的一个,颜值即正义,既然我无法放弃 Ant Design ProUI,那干脆模仿 Ant Design ProUI,自己来实现一个较为简单的版本

我在日常开发中发现,大部分开发人员,在日常开发中,用的都是别人的模版,而且只关注业务实现,忽视了系统的底层实现,大部分时间都用来做重复无意义的工作,对自己的提升微乎其微,一个很重要的原因就是

开源模版底层实现逻辑复杂,封装层级深,代码对新手不友好
复制代码

所以在开发这个系统时,在某些地方,我并没有太过封装,让使用这个模版的人都能看懂里面的每一行代码,同时能基于这个模版优化出最适合自己业务场景的一个通用模版,而不是永远在别人的模版之上coding

另外,我比较提倡优质的代码应该是浅显易懂的,而不是代码量最少,应避免因过于封装而导致逻辑晦涩难懂,对于新手来说非常不友好。

  • 从零使用 react 搭建系统
  • 全面使用 react-hooks 开发,抛弃 class 组件写法、所有组件异步加载,提高首屏渲染速度
  • 动态权限设计,实现路由菜单动态获取
  • 完成基本的用户登录、注册、找回密码功能
  • 基于eggjs、typescript 完整搭建基本模版
  • 集成 redis、mysql 数据库相关
  • 实现基本的用户系统、权限管理系统、短信发送、文件上传等功能
  • UI 框架: reactreact-hookclassnames
  • UI 组件: antd@ant-design/aliyun-theme
  • 数据管理reduxreact-reduxredux-thunkredux-logger
  • 类型检查typescript
  • 接口请求axios
  • cookiesjs-cookie
  • 过渡动画react-transition-group
  • CSS 规则BEM
  • 后端 APInodejseggjstsmysqlsequelize

那么,在这个系统中,能够获得什么,我分别列举

  1. 如何使用 react-hooks, useEffect, useCallback, lazy, memo, Suspense...
  2. react 生态配合 typescript 时,每一个都应该如何去使用?
  3. react 中使用 axios 时,应该如何将 axiostypescript 结合起来,并统一封装
  4. 日常开发中面临的一些常规问题,这里面大多都能找到
  5. 完整的从提交表单到接口响应数据渲染的一个过程
  6. 完整的权限系统搭配API实现的模版相对较少
  1. nodejseggjstypescriptredismysql 该如何使用
  2. eggjs 的扩展,中间件,插件等如何配合ts使用
  3. eggjs 统一的权限验证、错误处理,自定义错误等的使用
  4. redismysqlsequelize 如何结合 ts 使用
  5. mysql 中表的关联处理,事物处理在这里都能找的到
  6. 日常中面临的一些常见需求,参数校验、短信发送,图片上传等等
1



1



1
# 在模版代码中,默认代理到本地的3300端口,也可以直接代理到我
# 在线上部署的接口上,但是不支持删除和修改一些内容,可以本地将api也跑起来

# 前端
$ git clone https://github.com/landluck/react-ant-admin.git
$ cd react-ant-admin
$ npm install
$ npm start

# 后端
$ git clone https://github.com/landluck/react-ant-admin-api.git
$ cd react-ant-admin-api
$ npm install
$ # 在运行之前,需要配置自己的redis、mysql参数,才能跑起来
$ npm run dev
复制代码
// 前端
const AdminConfig: Config = {
  // react-router basename
  BASENAME: '/react-ant-admin',

  // 请求成功状态码
  SUCCESS_CODE: 200,

  // 登录过期,或者未登录
  LOGIN_EXPIRE: 400,

  // 统一请求地址
  API_URL: 'https://www.landluck.com.cn/react-ant-admin-api',

  // 本地存储token 的key
  TOKEN_KEY: 'Admin_Token_key',

  // 默认菜单栏位置
  layout: 'side',

  // 默认主题颜色
  theme: 'dark',

  // 是否固定头部
  fixedHeader: false,

  // 固定宽度或者流式宽度
  contentWidth: 'fixed',

  // 是否开启色弱模式
  colorWeak: false,

  // 项目名称
  title: 'React Ant Admin',

  // logo
};

// 后端
export default () => {
  const config = {} as PowerPartial<EggAppConfig> & { sms: AliyunSmsConfig, oss: OssConfig, };

  // override config from framework / plugin
  // use for cookie sign key, should change to your own and keep security
  config.keys = '_1554196283322_156_xxx';
  // 启动的端口和域名
  config.cluster = {
    listen: {
      port: 3300,
      hostname: '127.0.0.1',
    },
  };
  // 文件上传的方式
  config.multipart = {
    mode: 'file',
  };
 //  egg-security 的配置,暂时关闭一些安全校验
  config.security = {
    xframe: {
      enable: false,
    },
    csrf: {
      enable: false,
    },
  };

  // 中间件配置
  config.middleware = [ 'errHandle', 'auth' ];
  
  // mysql 配置
  config.sequelize = {
    dialect: 'mysql',
    host: '127.0.0.1',
    port: 3306,
    username: 'react-ant-admin',
    password: 'xxx',
    database: 'react-ant-admin',
    logQueryParameters: true,
    define: {
      timestamps: true,
      underscored: true,
      paranoid: true,
      freezeTableName: true,
    },
  };
  // redis 配置
  config.redis = {
    client: {
      port: 6379,
      host: '127.0.0.1',
      password: '123456',
      db: 2,
    },
  };
  // auth 中间件配置,
  config.auth = {
    // 不需要鉴权的接口url
    url: new Set([ '/user/login', '/user/login-mobile', '/', '/sms' ]),
    // ignore (ctx: Context) {
    //   return ctx.url.indexOf('.') !== -1
    // }
  };
  // sms 配置,默认使用阿里云
  config.sms = {
    accessKeyId: 'xxxx',
    accessKeySecret: 'xx',
    endpoint: 'https://dysmsapi.aliyuncs.com',
    regionId: 'cn-hangzhou',
    verifyCode: {
      signName: 'xxx',
      templateCode: 'xxx',
    },
    // 单个手机号每天可发送短信条数
    countByMobile: 10,
    // 单个ip每天可发送短信条数
    countByIp: 30,
  };
  // 文件上传配置
  config.oss = {
    // 七牛云的配置
    qiniu: {
      accessKey: 'xxx',
      secretKey: 'xxxx',
      scope: 'xxxx',
      host: 'xxxx',
    },
    // 文件上传到本地服务器的配置
    local: {
      prefix: '/public/image',
      dir: '/app/public/image',
    },
  };

  // the return config will combines to EggAppConfig
  return {
    ...config,
  };
};
复制代码

目前来说,react 模版的话,开源的暂时应该没有使用 react16 新特性开发的,对应的eggjs相关的开源项目,结合ts使用的比较少,其中面临的业务场景也不多(2019年12月调研),目前来说,这个模版只是一个最基础的内容,后期会基于这个模版开源一个其他的项目,模版的内容也会陆续添加 如果对大家有所帮助的话,希望给作者点个赞👍吧


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK