在线客服

如何结合整洁架构和MVP模式提升前端开发体验(三) - 项目工程化配置、规范篇

adminadmin 报建百科 2024-04-25 130 9
如何结合整洁架构和MVP模式提升前端开发体验(三) - 项目工程化配置、规范篇

我报名参加1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情

工程化配置

还是开发体验的问题,跟开发体验有关的项目配置无非就是使用 eslint、prettier、stylelint 统一代码风格

formatting and lint

eslint、prettier、stylelint 怎么配这里就不说了,网上文章太多了。想说的是eslint rule 'prettier/prettier': 'error'一定要开启,以及 stylelint rule 'prettier/prettier': true 也一定要开启。

虽然配置了eslint、prettier、stylelint,但是可能你队友的编辑器并没有装相应的插件,格式化用的也不是 prettier,然后他修改一行代码顺便把整个文件格式化了一遍。所以还得配置 husky + lint-staged,提交代码的时候按规范格式化回去,不符合规范的代码不允许提交。

如果公司的电脑配置还行的话,可以开发阶段就做相应的 lint, 把错误抛出来,中断编译。webpack 可以使用 eslint-loader,stylelint-webpack-plugin;vite 可以使用 vite-plugin-eslint,vite-plugin-stylelint;vue-cli 配置几个参数就可以开启,具体看文档。

ts-check

什么是 ts-check?举个例子,有一个后端接口的某个字段名称变了,由 user_name 改为了 userName,如果没有配置开发阶段进行 ts-check 并把错误抛出来,那么只能全局查找调用接口的地方去修改,如果改漏了,那就喜提一个 BUG。

ts-check 可以开发阶段就做,也可以提交代码的时候做。开发阶段 webpack 安装 fork-ts-checker-webpack-plugin ,vite 也是找相应的插件(暂时没找到用的比较多的)。提交代码的时候,结合 husky 做一次全量的 check (比较耗时),react 项目执行 tsc --noEmit --skipLibCheck,vue 项目执行 vue-tsc --noEmit --skipLibCheck

ts-check 能好用的前提是你的项目是 TS 写的,接口返回值有具体的类型定义,而不是 any。

代码规范

主要讲讲 model,service,presenter,view 这几层的代码规范,之前的文章也有简单提到过,这里做个归纳。

model

import { reactive, ref } from "vue";
import { IFetchUserListResult } from "./api";

export const useModel = () => {
  const userList = reactive<{ value: IFetchUserListResult["result"]["rows"] }>({
    value: [],
  });
 
  return {
    userList,
  };
};

export type Model = ReturnType<typeof useModel>;

  1. 每一个字段都要声明类型,不要因为字段多就用 Object[k: string]: string | number | booleanRecord<string, string> 之类的来偷懒。
  2. 可以包含一些简单逻辑的方法,比如重置 state。
  3. vue 中字段声明可以移到 useModel 外面,达到状态共享的作用,在 useModel 中 return 出去使用。

service

  1. react 技术栈,presenter 层调用的时候使用单例方法,避免每次re-render 都生成新的实例。
  2. service 要尽量保持“整洁”,不要直接调用特定环境,端的 API,尽量遵循?依赖倒置原则。比如 fetch,WebSocket,cookie,localStorage 等 web 端原生 API 以及 APP 端 JSbridge,不建议直接调用,而是抽象,封装成单独的库或者工具函数,保证是可替换,容易 mock 的。Taro,uni-app 等框架的 API 也不要直接调用,可以放到 presenter 层。组件库提供的命令式调用的组件,也不要使用。
  3. service 方法的入参要合理,不要为了适配组件库而声明不合理的参数,比如某个组件返回 string[] 类型的数据,实际只需要数组第一个元素,参数声明为 string 类型即可。2个以上参数改为使用对象。
  4. 业务不复杂可以省略 service 层。

service 保证足够的“整洁”,model 和 service 是可以直接进行单元测试的,不需要去关心是 web 环境还是小程序环境。

import { Model } from './model';

export default class Service {
  private static _indstance: Service | null = null;

  private model: Model;

  static single(model: Model) {
    if (!Service._indstance) {
      Service._indstance = new Service(model);
    }
    return Service._indstance;
  }

  constructor(model: Model) {
    this.model = model;
  }
}

presenter

import { message, Modal } from 'antd';
import { useModel } from './model';
import Service from './service';

const usePresenter = () => {
  const model = useModel();
  const service = Service.single(model);

  const handlePageChange = (page: number, pageSize: number) => {
    service.changePage(page, pageSize);
  };

  return {
    model,
    handlePageChange,
  };
};

export default usePresenter;

  1. 处理 view 事件的方法以 handle 或 on 开头。
  2. 不要出现过多的逻辑。
  3. 生成 jsx 片段的方法以 render 开头,比如 renderXXX。
  4. 不管是 react 还是 vue 不要解构 model,直接 model.xxxx 的方式使用。

view

  1. 组件 props 写完整类型。
  2. jsx 不要出现嵌套的三元运算。
  3. 尽量所有的逻辑都放到 presenter 中。
  4. 不要解构 presenter 以及 model,以 presenter.xxx,model.xxxx 方式调用。

store

  1. 不要在外层去使用内层的 store。

接口请求方法

  1. 封装的接口请求方法支持泛型
import axios, { AxiosRequestConfig } from "axios";
import { message } from "ant-design-vue";

const instance = axios.create({
  timeout: 30 * 1000,
});

// 请求拦截
instance.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.reject(error);
  },
);

// 响应拦截
instance.interceptors.response.use(
  (res) => {
    return Promise.resolve(res.data);
  },
  (error) => {
    message.error(error.message || "网络异常");
    return Promise.reject(error);
  },
);

type Request = <T = unknown>(config: AxiosRequestConfig) => Promise<T>;

export const request = instance.request as Request;

  1. 具体接口的请求方法,入参及返回值都要声明类型,参数量最多两个,body 数据命名为 data,非 body 数据命名为 params,都是对象类型。
  2. 参数类型及返回值类型都声明放在一起,不需要用单独的文件夹去放,觉得代码太多不好看可以用 region 注释块折叠起来(vscode 支持)。
  3. 接口请求方法以 fetch,del,submit,post 等单词开头。
  4. 建议接口请求方法直接放在组件同级目录里,建一个 api.ts 的文件。很多人都习惯把接口请求统一放到一个 servcies 的文件夹里,但是复用的接口又有几个呢,维护代码的时候在编辑器上跨一大段距离来回切换文件夹真的是很糟糕的开发体验。
// #region 编辑用户
export interface IEditUserResult {
  code: number;
  msg: string;
  result: boolean;
}

export interface IEditUserParams {
  id: number;
}

export interface IEditUserData {
  name: string;
  age: number;
  mobile: string;
  address?: string;
  tags?: string[];
}

/**
 * 编辑用户
 * http://yapi.smart-xwork.cn/project/129987/interface/api/1796964
 * @author 划水摸鱼糊屎工程师
 *
 * @param {IEditUserParams} params
 * @param {IEditUserData} data
 * @returns
 */
export function editUser(params: IEditUserParams, data: IEditUserData) {
  return request<IEditUserResult>(`${env.API_HOST}/api/user/edit`, {
    method: 'POST',
    data,
    params,
  });
}

// #endregion

上面代码是工具生成的,下篇说说提升开发效率及体验的工具。

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!
代办报建

本公司承接江浙沪报建代办施工许可证。
联系人:张经理,18321657689(微信同号)。

喜欢0发布评论

9条评论

  • 游客 发表于 5个月前

    不错哦,楼主这是要火的节奏啊!http://bbs.kdhlpt.com/article/2042988.html

  • 游客 发表于 5个月前

    哥回复的不是帖子,是寂寞!https://sdceda.com/seo/010827207/

  • 游客 发表于 5个月前

    好好学习楼主的帖子!http://test.cqyiyou.net/test/

  • 游客 发表于 4个月前

    很给力!http://www.3553km.com

  • 指尖站群 发表于 4个月前

    楼主说的我也略懂!http://www.datingcoquin.com/

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址