Skip to content

已我在 xx 公司的经历,重新制定,一个 2 ~ 4 人的前端小组,当前模板只是我个人的总结,不存在任何参考价值

制定目标

确定领导所要的目标

我的领导给的目标很简单,完成业务需求,涉及到的有管理后台、H5 和官网之类的应用,并且要有一套内部的组件库和开发规范,可以让新同事快速上手开发。

分析目标

我们部门开发的项目有分自研和外包两种形式,基本一些大型的项目,比如 OMS、商城等项目是由外包团队开发的,而门户、集成系统、官网等应用,则使用自研的方式。

而我们针对的是自研项目,基于此进行目标的分析:

  1. 有自己的开发规范
  2. 可以稳定控制代码产出的质量
  3. 能使新人快速上手

长期目标

可以基于长期目标再去拆分不同的阶段,逐步完成:

  1. 长期维护前端开发规范
  2. 构建前端小组的知识库
  3. 搭建前端基础工具,提供封装的组件,提升开发效率和降低维护成本
  4. 构建前端监控工具,监控和收集应用数据,优化应用性能和用户交互
  5. 持续优化前端开发流程和前端项目的部署流程

短期目标

短期目标是刚接手时需要先快速输出的内容:

  1. 输出基础版的前端规范
  2. 规范好前端在项目中开发的开发流程
  3. 输出项目模板和二次封装一个 UI 组件库,固定代码产出方式
  4. 搭建前端项目的 CI & CD

复盘方式

TODO...

制定开发规范(技术栈、开发规则和版本控制和协作)

文件组织

只针对新项目,旧项目还是按照旧项目的风格开发

业务项目目录结构

shell
.
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── public
   └── favicon.ico
├── src # 业务文件
   ├── App.vue # 入口 Vue 文件
   ├── asset # 静态文件
   ├── component # 组件
   ├── hooks
   ├── main.js # 入口文件
   ├── page # 页面
   ├── router # 路由配置
   ├── store # store
   └── utils
└── vite.config.js

库/包目录结构

shell
.
├── CHANGELOG.md
├── README.md
├── __tests__
   └── utils2.test.js
├── env.d.ts
├── index.html
├── lib
├── package-lock.json
├── package.json
├── package # 实现文件
   └── index.ts # 入口文件
├── src # 测试运行文件,最终打包不包含该文件夹
   ├── App.vue
   ├── index.ts
   └── views
├── tsconfig.app.json
├── tsconfig.build.json
├── tsconfig.config.json
├── tsconfig.json
├── tsconfig.vitest.json
└── vite.config.ts

命名方式

文件夹

1. 方式:kebab-case
2. 例子:
	1. `page`
	2. `component`
	3. `business-component`

文件

1. 方式:使用 `.` 分隔,需要根据相关的上下携带,比如页面,存储,路由,组件等
2. 其他规则:Vue 组件和 .vue 的页面文件名,首字母都需要大写,`index.vue` 除外
3. 例子:
	1. `About.vue`
	2. `about.js`
	3. 存储:`about.store.js`
	4. 路由:`product.route.js`
	5. 页面:`Product.page.vue`
	6. 组件:`Menu.com.vue`

CSS/SCSS

  1. 类名:
    1. 方式:使用类似 BEM 命名方式,用 - 分隔,按模块名命令
    2. 其他规则
      1. 页面组件中的根节点,要以 p- 开头,后接文件名
      2. 其他组件中的根节点,要以 c- 开头,后接组件名
      3. 不一定全部 class 都要以该规则命令,比如某些深层次的节点,可以直接用带语义化的命名:title, desc, item
    3. 例子:
      1. 页面:p-product, p-news
      2. 页面内的其他节点:p-news-list, p-news-item-title
      3. 组件:c-list
      4. 组件内的其他节点:c-list-title
      5. 布局文件:l-default, l-application
  2. CSS 变量:
    1. 方式:按模块划分,用 - 分隔
    2. 其他规则
      1. 颜色要以 c 开头,
      2. 字体大小以 fs 开头
      3. 如此类推
    3. 例子:
      1. --c-primary, --c-danger
      2. --fs-title, --fs-base
  3. SCSS 变量:
    1. 方式:按模块划分,用 - 分隔
    2. 其他规则
      1. 和 CSS 变量规则一致
    3. 例子:
      1. $c-primary, $c-danger

JavaScript

1. 方式:驼峰
2. 其他规则:
	1. 类需要首字母大写,其他首字母小写
3. 例子:
	1. 类:`ApiClass`
	2. 变量:`list`, `productList`

常量

1. 方式:大写 + 下划线分隔
2. 例子:
	1. `PROJECT`, `PROJECT_CODE`, `APPLICATION_PUBLIC_KEY`

TypeScript

1. 方式:根据定义的类型首字母大写开头 + 驼峰
2. 例子:
	1. 类型:
		1. `type TType = string | number`
		2. `type TProjectType = string | boolean`
	2. 接口:
		1. `interface IApiItem {}`
		2. `interface IProjectItem {}`
	3. 枚举:
		1. `enum EType = {}`
		2. `enum EProjectType = {}`

Vue

  1. name 属性
    1. 方式:首字母大写 + 驼峰
    2. 其他规则:
      1. 每个 .vue 都必须要有该属性
  2. 使用自定义组件:
    1. 方式:kebab-case
    2. 例子:
      1. <product-list />

代码风格

基于 Eslint 规则统一代码风格。

Eslint 规则清单: TODO...

技术栈

组件化规范

Vue 组件必须声明 name 属性

vue
<script>
export default { name: "ProductItem" }
</script>

尽量减少通过 ref 控制子组件

常见的弹窗组件,父组件需要控制子组件的显隐,而子组件也能触发隐藏,这时候不要使用 ref.show 之类的方式要控制,使用 v-model

Vue3

父组件

vue
<template>
  <child v-model:isShow="isShow" />
  <button @click="show">show</button>
</template>

<script setup>
import { ref } from 'vue'
const isShow = ref(false)

const show = () => isShow.value = true

</script>

子组件

vue
<template>
  <div v-show="curShow">child</div>
</template>

<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
  isShow: Boolean
})
const emits = defineEmtis(['update:isShow'])

const curShow = ref(props.isShow)

watch(() => props.isShow, (val) => {
  curShow.value = val
})

const hide = () => {
  emits('update:isShow',false)
}

</script>

组件拆分

当一个页面或一个组件有大量的内容时,就需要按模块进行拆分,就算这个模块不是重用的。这样做的原因:

  1. 更直观地看到整个模块的结构
  2. 方便重构
  3. 方便单测

Css

尽量避免使用负的 marginposition: relative 时的 top, right, bottom, left

因为这会产生额外的空间,维护麻烦

不要嵌套使用 /deep/

会导致某些浏览器没效果,例如 safari

JavaScript

export 的使用

比如我们要弄个公共方法或者变量,要按下面的方式:

export const testConfig = 'test'

export function testFunction() {}

// 使用:
import { testConfig } from '@/config'
// 或者想要拿这个文件的所有导出的变量
import * as testObj from '@/config'

什么时候应该使用 export default

当你这个文件只有一个对象或者方法的时候。如果你不确定这个文件后面是否还会扩展,那就使用 export 而不是 export default

TypeScript

Vue

定义 vue router

在定义 vue 的 router 的时候,要在 meta 里把页面的 title 和路由的 name 给定义了

javascript
{
  path: '/permission',
  name: 'permission',
  meta: { title: '权限管理' }
}

NestJs

注释与文档

文件顶部注释

VsCode 用户可以使用 koroFileHeader-hostname 这个插件,生成的注释如下:

javascript
/*
 * @Author: Lu
 * @Date: 2021-11-10 14:31:54
 * @LastEditTime: 2023-03-01 10:13:17
 * @LastEditors: Lu
 * @Description:
 */

异常处理

调试

PC

日志

浏览器的开发者工具 ![[a1.png]]

H5

日志

工具库

用的最多就是 vConsole 还有另外一个 eruda eruda 的 UI 相比 vConsole 更好,直接推荐用 eruda

shell
npm install eruda --save
javascript
import eruda from 'eruda';
eruda.init();

但这种库还是没有浏览器的开发者工具完善,所以我们可以通过连接手机,在浏览器查看 H5 的情况

ios

条件:

  1. 有一台 MacOs 系统的电脑

  2. 电脑打开 safari

  3. 手机用线连接电脑

  4. 手机 -> 设置 -> safari -> advanced -> 勾选 Web Inspector

  5. 在电脑的 safari -> 开发 -> 找到你手机的名称 -> 选择对应的页面进行监控 ![[a2.png]]

Android

  1. 保证电脑和手机的是同一个网络

动态缩放方案

使用 rem 方案

日志

测试

单测

对于库,有多余时间下,一定要做单元测试

自测

版本控制

git commit 规范

添加 git commit 规范,形成一个统一标准输出,方便查看对应每个版本的信息,并有利于自动化生成修改日志。 这里使用的 commit 规范是:@commitlint/config-angular 公式:类型: [主题内容] 例子:feat(project): 添加新产品,fix(project): 修复产品逻辑错误

类型

什么场景用什么类型的信息:

  • build:构建项目
  • ci:添加 ci
  • docs:添加文档
  • feat:添加功能
  • fix:修复问题
  • perf:优化功能
  • refactor:重构功能
  • revert:回退代码
  • style:修改代码样式
  • test:添加测试
  • chore:添加一些无关紧要的内容

作用域

作用域不是必填的,主要是说明这次改动的范围。

主题内容

主题内容又包含三块内容:

  1. 具体内容
  2. 是否打断版本?(可选)
  3. 添加打断的对应内容
  4. 是否解决什么问题?(可选)
  5. 解决哪个问题

例子

shell
# 完成某个模块
git commit -m 'feat(project): 完成弹窗部分;完成对接接口'
# 修复某个 bug
git commit -m 'fix(news): 修复 title 字段获取异常的问题'
# 修改了一些和业务、功能无关的内容
git commit -m 'chore: 移除注释'
# 文档相关
git commit -m 'docs: 优化文档内容'
# 性能相关
git commit -m 'perf: 优化首页渲染性能'
# 重构
git commit -m 'refactor(project): 重构弹窗部分的实现'

Git Fork 协作流程

现在有 warehouseA,属于 /fe 组的。B 同事需要进行开发,现需要进行以下准备操作:

  1. 进入 warehouseA 的 gitlab 页面,点击页面的 fork 按钮,复制该仓库到个人名下
  2. git clone fork 后的仓库到本地
  3. 在本地代码,设置源仓库的源:git remote add upstream {url} 完成以上配置后,在每次开发前需要先确认好两件事:
  4. 确认好开发的分支,保持本地仓库的开发分支和源仓库的开发是一致的
  5. 每次写代码前,要先拉取代码,同步本地代码和源仓库分支的代码,git pull upstream {branch_name} 当完成开发后,需要将代码合并到源仓库分支时,则要去到 GitLab 提交一个 MR 请求,让相关负责人进行代码合并

项目开发的版本控制

安全性

TODO...

协作

TODO...

工具、资源

编辑器/IDE

开发相关的工具

其他效率工具

  • 快速启动工具
  • Markdown 工具
  • 知识管理工具
  • 压缩/解压
  • 颜色获取
    • MacOs
      • RayCast 插件 - Color Picker
  • 粘贴板
    • MacOs
      • RayCast 插件 - Clipboard History
  • 截图
  • 录屏
  • 二维码
    • 草料
  • 视频压缩、转换
    • MacOs
      • [Focus Video]
  • 窗口尺寸控制工具
  • 设计工具
    • 蓝湖
    • Photoshop
    • MacOs
      • Sketch

项目开发

开发时需要明确的内容

  • 项目需要兼容什么浏览器,IE 需要吗?
  • 什么端,PC 还是 H5
  • 部署到什么服务器
  • 用什么方式部署?Jenkins?
  • 测试环境用哪个
  • 后端对接人是谁?
  • 项目提测时间
  • 项目上线时间
  • 项目负责人