静态数据

所谓静态数据,本文内指的是一些静态常量、配置化数据以及枚举类数据等,很少变化或者说很少在运行时变化的数据。

例如:API 服务器的 rootPath、常用的正则表达式、业务相关的枚举类数据、固定的填充数据以及 i18n 等。

虽然这些数据很少变化,但在一个大的项目中非常容易到处使用。常见的问题有:

  • 同样规则的正则表达式,这写一个,那写一个
  • 业务枚举数据各种迷之 magicNumber 进行判断比较,如 if(this.type === 1)1 是啥???
  • 对同一种数据的多处定义,A 组件一个 framework: ['Vue', 'React', 'Angular'],B 组件用的时候又定义一次
  • i18n 时,不同模块中的类型场景定义多个描述
  • ……

这些问题的出现就给后期项目维护增加了时间和沟通成本,有意识的提取静态数据是必须要做的事。

静态数据分离

配置、工具类数据

类似 AJAX、WebSocket 等常用模块配置,可以抽取到一个公共的 appConf.js 文件中,通过引用配置文件对模块进行配置。常用的正则也抽取到一个工具模块中。类似的还有校验类数据,比如允许用户上传的文件大小、文件类型等。

枚举类数据

一个用户的角色、权限、状态等数据,前端接收到的一般是 { role: 0, state: 1 } 这种,那么在代码中通常有三种使用场景:

  1. 内容展示:user.role === 0 ? '管理员' : '成员'
  2. 权限判断:user.role === 0 && doSomething()
  3. 选择、过滤时的列表展示:[{ value: 0, text: '管理员'}, { value: 1, text: '成员'}]

此类数据后端都犯不着建个表存储,定个枚举类完事。如果是前后端同构的项目,大家都调用同一个枚举模块就行了。多数情况下,前端也需要对此类数据集中化管理,让之后的代码维护有路径可寻。

我的做法有:

  1. 由于 JS 目前没有内置枚举类,可以使用对象模拟,或者自己包装一个枚举类的实现。
  2. 抽取到前端 service 层,与同一模块下的业务函数放一块。

个人更倾向于第二种:

// userService
export const MAGANER = 0
export const MEMBER = 1
export const isManager = role => MAGANER === role
export const isMember = role => MEMBER === role

i18n

i18n 的数据不仅要按业务模块纵深划分,还要考虑横切的通用类数据。

  • 纵深:user、project、docs…
  • 横切:action、date、httpCode…

如果只按模块划分,那么可能就会出现重复定义的按钮文字、触发动作等,如下:

{
user: {
enter: '保存',
remove: '删除',
msgcode: {
10001: '添加用户成功!'
}
},
project: {
save: '保存',
deleted: '删除',
msgcode: {
10001: '添加项目成功!'
}
}
}

重复场景、语义的文字多处定义,而且属性名也不一致。改善后:

{
action: {
enter: '确认',
save: '保存',
remove: '删除'
},
httpcode: {
10001: '添加{0}成功!'
},
user: {},
project: {}
}

END

内容没什么技术含量,纯粹是出于代码洁癖,就是不想在项目看见任何重复的东西。