背景
为了统一团队的研发方式,对团队代码资产的目录结构做最佳实践的统一规范,降低对于各类代码资产的理解、维护成本,并方便统一的构建和管理。
规范细则
以下关键词 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的叙述解读。
目录划分原则
-
根目录下必须(MUST)按照职能进行划分,禁止(MUST NOT)按照业务功能进行目录划分,帮助开发同学快速聚焦关注点
-
根目录下文件夹必须(MUST)只能包含src/、bin/、config/、tests/、public/、build/ 这六个。
- src文件夹下存放业务源码
- config文件夹下存放配置相关文件
- public文件夹下存放通用html模版
- bin文件夹下存放执行脚本文件
- build文件夹下存放打包后代码
- tests文件夹下存放测试相关代码
-
根目录下还应该(SHOULD)包含package.json、README.md、yarn.lock、.commitlintrc.js、.cz-configrc.js、.editorconfig、.eslintrc.js、.stylelintrc、babel.config.js、.eslintignore、.gitignore、.stylelintignore、.npmrc、vue.config.js、tsconfig.json、.env.*等配置文件。其中必须(MUST)包含package.json、README.md、yarn.lock、.commitlintrc.js、.cz-configrc.js、.editorconfig、.eslintrc.js、.stylelintrc、babel.config.js来完成依赖管理、工程说明、依赖版本锁定以及代码书写规范约束。
-
-
对于业务不需要分包进行独立管理依赖的情况在src下面直接按照职能类型进行划分
-
src下必须(MUST)是components/、lib/、api/、plugins/、assets/、styles/、pages/中的若干个。随着资源职能的增加可能会增加对应的目录,例如目前探索的hooks纯逻辑复用方式,可申请新增。
-
公共组件应该(SHOULD)放在components/下面
-
组件必须(MUST)创建组件文件夹进行放置
-
组件可以(MAY)在多层目录下放置,如 components/module-a/module-b/.../componentxx
-
[规范补充]:
-
根节点组件定义:导出一个index.vue文件的文件夹则被视为根节点组件,即该文件夹下应该只包含书写这个组件所需要的资产。
-
根节点组件目录结构
-
必须导出index.vue文件作为组件的解析入口
-
子目录可以(CAN)包含 components/styles/assets/api这几个文件夹,除此之外不可以包含其他文件夹
- components:存放该业务组件的子组件
- styles:存放该业务组件抽取的样式文件,不过更推荐内联到.vue文件中
- assets:存量只属于该组件静态文件如图片
- api:存放只属于该组件的api文件
-
其中components下和src下components目录规范要求相同,不过原则上应该只包含它父组件的子组件
-
-
-
-
-
组件必须(MUST)实现index.vue文件来导出组件
-
组件的注释规范见[资产注释规范]
-
-
公共工具函数应该(SHOULD)放在lib/下面
-
公共后台接口服务应该(SHOULD)放在api/**下面
- 如果要放置页面api文件,推荐( RECOMMENDED)和页面文件夹名称对应。
-
公共插件、过滤器(Vue.filter)、自定义指令(Vue.directive)应该(SHOULD)放在plugins/**下面
- 公共插件推荐( RECOMMENDED)实现Vue.use(plugin),页面只需引入即可使用
-
公共静态资源如图片应该(SHOULD)放在assets/**下面
- assets下如需按照静态资源类型存放可按照imgs、fronts、js、css进行划分。
-
公共动态样式文件应该(SHOULD)放在styles/**下面
-
页面必须(MUST)放在pages/下面
-
页面代码必须(MUST)创建页面文件夹进行放置,如pages/businessxx/
-
页面文件夹中必须(MUST)实现main.js和app.vue文件
-
页面文件夹中允许(SHOULD)包含页面级别的 components/、lib/、api/、assets/、styles/、router/、store/、views/文件夹
-
如果该页面为单页应用入口,其中单页的页面文件必须放在views/文件夹下面,如 views/businessxx.vue
-
views下的一个单页应用的页面必须(MUST)实现.vue的单文件,或按如下规则内聚:
- views/xx 可以作为一个单独的模块,允许(MAY)有模块自己的 api、lib、styles、components 子目录
- 子目录都同样支持多级嵌套
- api 和 lib:允许 .js、.ts 文件,分别放请求代码和工具/配置代码
- styles:允许 .scss、.css 样式文件
- components:内部和公共组件目录规范细则一致
- 如果只有一个文件不希望建一个单独的子目录,也可以直接在模块中创建 api.{js|ts}、lib.{js|ts}、styles.{scss|css} 这几个单文件
-
views下的一个单页应用页面可以(MAY)在多层目录下放置,如 views/module-a/module-b/.../businessxx.vue
-
-
单页应用的路由配置放在router/文件夹下,入口为index.js
-
单页应用的全局数据相关放在store/文件夹下,入口为index.js
-
如果页面要自定义html模版,则还可以(MAY)包含businessxx.html文件,其中businessxx和页面文件夹同名。
-
-
-
-
TS 工程的目录结构和 ES 工程基本一致。允许在 src 目录放置 types、Must 级别的 .js 文件可以修改为 .ts 文件
-
对于业务需要使用多包方式独立管理依赖的情况,src下增加packages,packages下按照业务功能划分目录,如src/packages/**/,业务功能文件夹下按照职能进行划分。原则同上。
目录命名原则
- 命名尽量简洁,有习惯缩写的单词用缩写的形式
- 目录和文件名称统一使用小写加连字符((kebab-case))
目录结构说明
一个复杂应用的目录结构如下,涵盖了中后台开发的各种功能和坑位。
代码块
system-demo
├─ src
│ ├─ components //页面间复用组件。根据组件模版生成的组件放在这个文件夹中。页面间复用的组件可以快速被沉淀为平台组件(发布为npm包,各个其他项目中以npm包的方式进行引用)
│ │ ├─ strong-hello-world
│ │ │ └─ index.vue //组件入口文件
│ │ ├─ module-a // 多级目录
│ │ │ ├─ module-b
│ │ │ │ ├─ home-page //组件根节点
│ │ │ │ │ ├─ components //[可选] 子组件目录,内部的目录结构和外层 components 目录一致
│ │ │ │ │ ├─ styles //[可选] 组件样式文件
│ │ │ │ │ │ └─ index.scss
│ │ │ │ │ ├─ assets //[可选] 组件静态资源
│ │ │ │ │ │ └─ home-page.png
│ │ │ │ │ ├─ api //[可选] 组件接口服务
│ │ │ │ │ │ └─ index.js
│ │ │ │ │ └─ index.vue //组件入口文件
│ ├─ lib //工具库
│ │ ├─ http.js
│ │ └─ axios.js
│ ├─ api //后台接口服务
│ │ └─ common.js //公共接口
│ ├─ plugins //[可选] vue插件(全局)
│ │ └─ mtd.js
│ ├─ assets //[可选] 静态资源
│ │ └─ pic.png
│ ├─ styles //[可选] 样式资源
│ │ └─ global.scss
│ ├─ pages //页面,pages下的每个文件夹都会被作为一个entry来进行打包(必须,打包时路由解析会依赖这个文件目录)
│ │ ├─ page-a // 每一个页面内部可以实现为一个spa
│ │ │ ├─ main.js //页面打包主入口
│ │ │ ├─ app.vue //页面入口vue文件,作为页面组件进行解析
│ │ │ ├─ router //spa路由配置
│ │ │ │ └─ index.js
│ │ │ ├─ store //[可选] 页面store
│ │ │ │ └─ index.js //store入口文件
│ │ │ ├─ views //视图文件,仅允许 .vue 文件
│ │ │ │ ├─ module-a //可多级嵌套
│ │ │ │ │ └─ module-a-page.vue
│ │ │ │ ├─ home-page.vue
│ │ │ │ └─ about-page.vue
│ │ │ ├─ lib //[可选] 页面级工具库
│ │ │ │ └─ page-a-utils.js
│ │ │ ├─ assets //[可选] 页面级静态资源
│ │ │ │ └─ about.png
│ │ │ ├─ styles //[可选] 页面级样式资源
│ │ │ │ ├─ home.scss
│ │ │ │ └─ about.scss
│ │ │ ├─ api //[可选] 页面级后台接口服务
│ │ │ │ └─ page-a.js //page-a接口
│ │ │ ├─ components // [可选] 页面级组件,比如使用到store的组件都可以放在此目录下
│ │ │ │ └─ pagea-hello-world
│ │ │ │ │ └─ index.vue
│ │ │ ├─ page-a.html //[可选] 页面打包模版,如果不想用默认打包模版可以自定义
│ │ ├─ page-b
│ │ │ ├─ main.js //打包主入口
│ │ │ ├─ app.vue //页面入口vue文件
│ │ │ ├─ store //[可选] 页面store
│ │ │ │ └─ index.js //store入口文件
│ │ │ ├─ api //[可选] 页面级后台接口服务
│ │ │ │ └─ page-b.js //page-b接口
│ │ │ ├─ components // [可选] 页面级组件,比如使用到store的组件都可以放在此目录下
│ │ │ │ └─ pagea-hello-world
│ │ │ │ │ └─ index.vue
│ │ │ ├─ page-b.html //[可选] 页面打包模版,如果不想用默认打包模版可以自定义
│ ├─ types //[可选] TS 工程类型声明文件
├─ public 必须 //默认项目打包html模版
│ └─ index.html
├─ README.md 必须
├─ package.json 必须
//标准化工程规范
├─ .commitlintrc.js 必须
├─ .cz-configrc.js 必须
├─ .editorconfig 必须
├─ .eslintignore 必须
├─ .eslintrc.js 必须
├─ .gitignore 必须
├─ .stylelintrc.js 必须
//工程配置文件
├─ .env.development 必须 //不同环境的变量配置
├─ .env.production 必须
├─ .env.staging 必须
├─ tsconfig.json [可选]
├─ vue.config.js //打包主配置文件
//工程配置文件
├─ config
│ └─ variables.config.js //其他打包所需配置文件,编译时插件可定制的配置文件
//执行文件
├─ bin
//打包文件夹build
├─ build
//单元测试文件
└─ tests
└─ unit
├─ .eslintrc.js
└─ example.spec.js
由于有业务团队有多包方式独立管理不同业务模块之间依赖的需求,因此同时研发框架的目录结构同时支持了多包目录结构,如下所示。
代码块
system-demo
├─ src
│ ├─ packages
│ │ ├─ bushiness1
│ │ │ ├─ ... //同上述目录结构中src中的内容
│ │ │ └─ package.json // package1独立业务依赖,如业务组件库等
├─ public 必须 //默认项目打包html模版
│ ├─ favicon.ico
│ └─ index.html
├─ README.md 必须
├─ package.json 必须
//标准化工程规范
├─ .commitlintrc.js 必须
├─ .cz-configrc.js 必须
├─ .editorconfig 必须
├─ .eslintignore 必须
├─ .eslintrc.js 必须
├─ .gitignore 必须
├─ .stylelintrc.js 必须
//工程配置文件
├─ .env.development 必须 //不同环境的变量配置
├─ .env.production 必须
├─ .env.staging 必须
├─ vue.config.js //打包主配置文件
//工程配置文件
├─ config
│ └─ variables.config.js //其他打包所需配置文件,编译时插件可定制的配置文件
//执行文件
├─ bin
//打包文件夹build
├─ build
//单元测试文件
└─ tests
└─ unit
├─ .eslintrc.js
└─ example.spec.js
工程内部资产生产规范
其中为了进行资产的结构化解析以及自动化构建能力,研发框架又规定了组件和页面的生产规范。
组件生产规范
其中页面间复用的组件(src下包含的components)和页面级组件(每个page文件夹下包含的components)都需要约定如下目录结构书写([组件目录结构规范])。必须实现index.vue文件作为组件的入口文件。方便研发框架对组件进行结构化的解析以及对接平台化的资产注册。注释规范遵循[资产注释规范]
代码块
├─ components //页面间复用组件。根据组件模版生成的组件放在这个文件夹中。页面间复用的组件可以快速被沉淀为平台组件(发布为npm包,各个其他项目中以npm包的方式进行引用)
│ └─ strong-hello-world
│ └─ index.vue //组件入口文件
│ └─ second-demo
│ └─ index.vue
│ └─ second.vue
页面生产规范
对于每个页面(pages下的每个文件夹),都需要实现main.js打包入口文件,以及app.vue的入口文件。方便统一构建做自动化的打包入口计算。
代码块
├─ pages //页面间复用组件。根据组件模版生成的组件放在这个文件夹中。页面间复用的组件可以快速被沉淀为平台组件(发布为npm包,各个其他项目中以npm包的方式进行引用)
│ └─ page-demo
│ │ ├─ main.js //页面打包主入口
│ │ ├─ app.vue //页面入口vue文件