前端企业级代码规范(巨详细)
前端规范目的是什么提高团队开发效率。有利于项目的后期维护。良好的代码规范,不仅能够让代码简洁清晰,还可以减少 bug 的出现,更能够让看代码的人赏心悦目。总结八个字: 统一规范方便高效1.编辑器风格参考google编码风格每行200字符后,建议换行 (若不影响可读性,可不进行换行)说明:虽然对于js推荐120个字符。但是为了方便vue组件视觉适应性,统一采用200个字符TAB键:默认 1个 TAB
前端规范目的是什么
- 提高团队开发效率。
- 有利于项目的后期维护。
- 良好的代码规范,不仅能够让代码简洁清晰,还可以减少 bug 的出现,更能够让看代码的人赏心悦目。
- 总结八个字: 统一 规范 方便 高效
1.编辑器风格
-
每行200字符后,建议换行 (若不影响可读性,可不进行换行)
- 说明:虽然对于js推荐120个字符。但是为了方便vue组件视觉适应性,统一采用200个字符
-
TAB键:默认 1个
TAB
为 4 个Space
- 说明:对于不同编辑器,使用空格,避免TAB间距不同造成视觉差。
-
注释符号之后,文本之前,必须加上空格
■ html,css,json都采用双引号
■ js 字符串都采用单引号
■ 示例
■ 说明:方便快速区分 模板,脚本,样式。
■ Js每行,属性方法结尾都加上【 ; 】
编辑器风格文件配置
当大家在公司工作时,不可能永远是一个人维护一个项目,当多个人参与一个项目,每个人使用的编辑器不一样,代码风格自然也不一样,那么如何让使用不同编辑器的开发者能够轻松惬意的遵守最基本的代码规范呢?
- .editorConfig(IDE统一风格文件)
- EditorConfig
- editorConfig不是什么软件,而是一个名称为.editorconfig的自定义文件。该文件用来定义项目的编码规范,编辑器的行为会与.editorconfig 文件中定义的一致,并且其优先级比编辑器自身的设置要高,这在多人合作开发项目时十分有用而且必要
- 有些编辑器默认支持editorConfig,如webstorm;而有些编辑器则需要安装editorConfig插件,如ATOM、Sublime、VS Code等
- 当打开一个文件时,EditorConfig插件会在打开文件的目录和其每一级父目录查找.editorconfig文件,直到有一个配置文件root=true
- EditorConfig的配置文件是从上往下读取的并且最近的EditorConfig配置文件会被最先读取. 匹配EditorConfig配置文件中的配置项会按照读取顺序被应用, 所以最近的配置文件中的配置项拥有优先权
- 如果.editorconfig文件没有进行某些配置,则使用编辑器默认的设置
- vsCode IDE统一风格插件 -> EditorConfig for VS Code
.editorConfig文件
[*.{js,jsx,ts,tsx,vue}] //* 匹配除/之外的任意字符串 [name] 匹配name中的任意一个单一字符 {s1,s2,s3} 匹配给定的字符串中的任意一个(用逗号分隔)
indent_style = space //设置缩进风格(tab是硬缩进,space为软缩进)
indent_size = 4 //用一个整数定义的列数来设置缩进的宽度,如果indent_style为tab,则此属性默认为tab_width
trim_trailing_whitespace = true //设为true表示会去除换行行首的任意空白字符。
insert_final_newline = true //设为true表示使文件以一个空白行结尾
2.注释
- 为了方便 高效 ,js代码注释达到80% 以上(看公司需求)
2.1.文件描述注释(文件创建时候)
- 内容:
FileDesc : 文件说明(页面作用,组件用途)
Author : SVN、GIT账号 工号
Date : 创建时间
Version : 版本 - 说明:查看该文件的用途,创建者,创建日期。方便在遇到问题的时候,快速找到对应的负责人
- 示例模板HTML / VUE
- 示例模板JS/css
2.2.文档注释
- 若无编译要求,可读性损失等特殊情况。方法之前,必须加入
2.3.多行注释
- 通常用于流程,详情,方法内说明
2.4.单行注释
- 【 // 】之后,需加上空格。 如: // comment
2.5.特殊标记注释
- 插件: TODO Tree
Note: 忽略大小写,可添加特殊符号,如 @
// TODO: 有功能代码待编写,待实现的功能在说明中会简略说明
// HOTFIX: 代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说明中简略说明
// BUGFIX: BUGFIX 相关描述
// N.B. 特别说明(Note Bell)
// LINK_TO: 与此问题相关解决方案 or issue
// HACK: 编写得不好或格式错误,需要根据自己的需求去调整程序代码
// NOTE: 说明代码如何工作
// INFO: 相关信息描述
// TAG: Tag 相关描述
3.命名(vue详细介绍)
3.1.命名种类
3.2.目录与普通文件的命名: kebab-case
说明:增强文件目录树可读性,对于不支持文件名大小写的磁盘系统,具有更好的适应和兼容性
3.3.VUE组件文件的命名: PascalCase
■ 完整单词,尽量减少使用存在歧义的缩写
■ 组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾
■ 和父组件紧密耦合的子组件应该以父组件名作为前缀命名
■ 公用基础组件名,前缀开头用 Base
■ 单例组件名(每个页面最多只用一次,不接受任何prop),前缀用 The
3.4.VUE 组件名命名
-
单文件组件和字符串模板,script 中都采用 PascalCase
说明:使用PascalCase定义的时候,容易区分vue组件和h5自带标签 -
在DOM模板中,采用kebab-case
说明:DOM模板中只支持kebab-case
3.5.VUE组件prop命名
- template 采用 kebab-case
- 说明:遵循html约定
- script采用 camelCase
- 说明:与js属性写法保持一致
3.6.VUE emit命名
- 名称采用 kebab-case
this.$emit(‘on-close-this-modal’); <button @on-close-this-modal=”handleModalClose”>close</button>
3.7.VUE 组件私有属性命名
- 采用 $yourPluginName
3.8.VUE route命名
- 采用 kebab-case
3.9. VUEX相关命名
- 采用 CAPITAL_CASE
-
说明:命名作为常量,都采用CAPITAL_CASE
3.10.VUE-CSS命名
- BEM思想 ,推荐
- 采用 block__element–modifier ,独立实体__实体的子模块–行为或状态版本等
具体内容请关注官网
- 采用 block__element–modifier ,独立实体__实体的子模块–行为或状态版本等
- views目录组件根标签样式命名
- views/Home.vue
说明:views目录下是用户直接访问的页面,采用view_作为前缀,能快速分辨出,该组件的作用
- views/Home.vue
- components目录组件根标签样式命名
- components/UserIdCard.vue
- components/UserIdCard.vue
- components-base目录组件根标签样式命名
- Components-base/BaseUserIdCard.vue
- Components-base/BaseUserIdCard.vue
- component-single目录组件根标签样式命名
- Components-single/TheUserIdCard.vue
- Components-single/TheUserIdCard.vue
4.编码建议
4.1.VUE - 相关
说明参考: VUE官方风格指南
■ 指令采用缩写形式
用 : 替代 v-bind:
用 @ 替代 v-on:
■ 为 v-for 设置 :key
■ 避免 v-if 和 v-for 同时出现在一个元素上
■ 善用 v-model.lazy,v-model.number,v-model.trim 等
■ 善用 directives,filter 等,有助于提高编码效率和代码易读性
■ Prop 定义应该语义化,尽量详细
■ 组件/实例的选项顺序
■ 隐性的父子组件通信
prop 向下传递,事件向上传递的
更清晰的数据流向,使用:value
,@input
减少在子组件直接使用 v-model="todo.text"
this.$parent
操作数据
■ 去除未用到的import组件
■ 环境变量
.env.development
NODE_ENV=development /* 环境 */
VUE_APP_PROJECT_TITLE= 企业级项目 /* 项目名 */
VUE_APP_WEB_PREFIX=/pcji /* 项目前缀 */
VUE_APP_PROXY_URL=http://xx.xxxxxxx.cn:8015 /* 本地代理 */
VUE_APP_SHOW_DOC=true /* 是否显示开发文档 */
VUE_APP_ENABLE_WEBSOCKET=false /* 是否允许调用websocket */
个人环境变量起名 (不要提交)
.env.development.zhangsan.local
4.2.常规编程 - 相关
■ 为不需要【TAB键】轮循到的可操作组件加上 tabindex=“-1”
- 说明:若用户采用TAB按键方式,切换输入框和按钮,需要忽略非表单组件
■ 将文件中超长的配置值移出到同级目录或配置目录的单独文件中
■ 一次逻辑嵌套尽量不超过3层
■ JS的 等于号 采用 “===”(三等号)
- 说明:采用 === 不仅是判断值,同时也判断了类型。
■ JS每行语句,都必须以”;”结尾
■ 变量名,参数名,函数名,方法/属性,命名空间 使用 camelCase
■ 常量名,枚举属性: CAPITAL_CASE
■ 类名,枚举名 :PascalCase
■ 私有(保护)成员 : $_camelCase
4.3.Style相关建议
■ 采用 scoped 域
■ 采用 less\sass 语言
■ 样式顺序(参考 csscomb)
- 说明:增强代码可读性
■ 建议用rem,配合media-queries 做好屏幕适配 *
1rem == 20px ,或 1rem == 100px
说明:若对于不同的屏幕,需要微调尺寸的时候,可以直接在根元素上加上 font-size: 125% (相当于 1rem == 20px),或者 font-size: 625%(相当于 1rem == 100px) 。因chrome默认最小12px,所以不推荐用 62.5%
5.小程序编码风格
■ 可复用组件化
■ 常用样式提取出来
■ 善用css3 自定义参数属性
■ 子组件 triggerEvent 命名,采用全小写lowercase
this.triggerEvent('myevent', myEventDetail, myEventOption)
6.代码的提交
■ 提交的代码,去掉 .idea .vscode 等编辑器配置文件
■ 提交的代码,去掉 debugger;
说明:提交断点代码,会给后续更新代码的同事造成很大不便。
■ 禁止提交node_modules目录内容,提交package.json 和 package-lock.json 即可
说明: node_modules目录,文件量大,项目众多情况,增加git或svn服务器负担。
而且,针对不同操作系统,node_modules的部分插件涉及二进制文件和包的需要重新编译
- 对于os与cpu的设置参见官方说明
注意:
单纯 package.json 会自动更新包
^2.3.4 会自动更新到 2.x.x (无package-lock.json)
~2.3.4 会自动更新到 2.3.x (无package-lock.json)
package-lock.json 锁定版本(优先级小于package.json。若package.json改变版本,则此文件也会被修改)
-
svn
■ svn代码提交格式(至少写一行说明)
【项目】: xxxx-后台管理-前端
【提交内容】: 提交后台管理前端源代码,修改内容:xxxx
【版本】: 1.0
【相关bug】:
【参与人】:说明:直接体现代码修改内容,方便在遇到问题的时候,可以将版本控制的描述作为另一个参考依据
■ svn代码提交步骤
更新 -》 锁定 -》 更新 -》 提交(解锁) -
git(推荐GIT文章)
■ git代码提交格式(commit至少写一行说明)
git commit -m “xxxx-后台管理-前端”
■ git代码提交步骤
git add -A
git commit -m “提交后台管理前端源代码,修改内容:xxxx”
git pull origin 分支 (pull下来有可能有冲突,解决冲突)
git push origin 分支7.node_modules管理
■ 禁止提交项目下的 node_modules 目录
■ 统一归档具有相同package.json项目的node_modules目录
■ 若有不同的package.json,请自行下载,并且归档至指定svn目录下,作为后续沿用项目的离线包
■ vue项目下新增一个 .nodemodulerc 文件,文件内容即离线归档目录的名称注意: 对于将node_modules归档的项目,此文件必须存在归档目录生成规则 node_modules_<随机6位字母数字>_
如: node_modules_ae82cv_2019-12-17
node_modules_3dv2s3_2019-12-19
8.业务配置推荐
- ESlint(Vue,React)配置推荐
- Prettier(Vue,React)配置推荐
- Git代码提交配置推荐
- webpack配置推荐
- .editorConfig(IDE统一风格文件)
[*.{js,jsx,ts,tsx,vue}] //* 匹配除/之外的任意字符串 [name] 匹配name中的任意一个单一字符 {s1,s2,s3} 匹配给定的字符串中的任意一个(用逗号分隔) indent_style = space //设置缩进风格(tab是硬缩进,space为软缩进) indent_size = 4 //用一个整数定义的列数来设置缩进的宽度,如果indent_style为tab,则此属性默认为tab_width trim_trailing_whitespace = true //设为true表示会去除换行行首的任意空白字符。 insert_final_newline = true //设为true表示使文件以一个空白行结尾
- VScode软件入门:用户自定义代码块+常用快捷键+常用扩展插件
-
setting.json配置
-
//@: TODO, 对应插件根据配置自行百度,后续填坑
{ "workbench.iconTheme": "vscode-icons", "editor.wordWrapColumn": 120, "explorer.confirmDelete": false, // 注释模板 "fileheader.configObj": { "autoAdd": false, // 检测文件没有头部注释,自动添加文件头部注释 // 默认注释 没有匹配到注释符号的时候使用。 "annotationStr": { "head": "<!--", "middle": "", "end": " -->", "use": true }, "prohibitItemAutoAdd": [ "项目的全称禁止项目自动添加头部注释, 使用快捷键自行添加" ] }, // 头部注释 "fileheader.customMade": { // 头部注释默认字段 "FileDesc": "", "Author": "ls", "Date": "Do not edit", // 设置后默认设置文件生成时间 // "LastEditTime": "Do not edit", // 设置后,保存文件更改默认更新最后编辑时间 // "LastEditors": "liusheng", // 设置后,保存文件更改默认更新最后编辑人 "Version": "", "Usage": "\n\t\t- template\n\t\t-\tjs\n\t\t- props\n\t\t- event\n\t\t- method" // "FilePath": "Do not edit", // 设置后,默认生成文件相对于项目的路径 // "custom_string_obkoro1": "可以输入预定的版权声明、个性签名、空行等" }, // 函数注释 "fileheader.cursorMode": { // 默认字段 "description": "", "param": "", "return": "" }, // //注释模板 // "fileheader.configObj": { // "specialOptions": { // "FilePath": "file", // "Author": "author", // "Date": "date", // "LastEditors": "lastEditors" // }, // "dateFormat": "YYYY-MM-DD", // 个人喜好 // "prohibitAutoAdd": ["json", "md"], // "colon": " ", // "language": { // // 一次匹配多种文件后缀文件 不用重复设置 // "js/ts/jsx/tsx": { // "head": "/**", // 统一增加几个*号 // "middle": " * @", // "end": " */" // } // } // }, // "fileheader.customMade": { // "FilePath": "Do not edit", // "author": "zhainanya", // "Date": "Do not edit" // }, // stylelint 自动格式化 "stylelint.autoFixOnSave": true, "stylelint.configOverrides": {}, //prettier 自动保存 "editor.formatOnSave": true, "editor.renderWhitespace": "boundary", // alias // "alias-skip.allowedsuffix": ["js","vue","jsx","ts","tsx"] , // "alias-skip.rootpath": "package.json", // "alias-skip.mappings": { // "@react-page":"/packages/react-page/src", // "@vue-page":"/packages/vue-page",å // "@": "/src", // 默认只有`@`映射,映射到`/src`,你可以添加更多映射,映射路径必须以`/`开头 // "components": ["/src/components"], // "assets": ["/src/assets"], // // ...更多映射关系 // }, //单击编辑 "workbench.editor.enablePreview": false, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" }, "workbench.startupEditor": "newUntitledFile", "explorer.confirmDragAndDrop": false, "workbench.colorTheme": "Default Dark+", "editor.fontSize": 13, // carbon,美化分享的代码片段 "carbon.backgroundColor": "rgba(171,184,195,100)", "carbon.theme": "vscode", "carbon.dropShadow": true, "carbon.windowControls": true, "carbon.autoAdjustWidth": true, "carbon.paddingVertical": 24, "carbon.paddingHorizontal": 16, "carbon.lineNumbers": false, "carbon.fontFamily": "Hack", "carbon.fontSize": 13, "terminal.integrated.shell.osx": "/bin/zsh", "javascript.updateImportsOnFileMove.enabled": "always", "vetur.format.options.tabSize": 4, // php tpl "files.associations": { "*.tpl": "html" }, "cSpell.userWords": ["onclickoutside"], "git.confirmSync": false, "files.saveConflictResolution": "overwriteFileOnDisk", "svg.preview.mode": "svg", "svg.minify.removeViewBox": false, "typescript.updateImportsOnFileMove.enabled": "always", "sync.gist": "057eca72034c58dfc0617eb42fa5b401", "bracket-pair-colorizer-2.depreciation-notice": false, // eslint 保存自动检测校正 "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, // eslint 图标状态 "eslint.alwaysShowStatus": true, "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact", "html", "vue", "markdown" ], // "[typescript]": { // "editor.defaultFormatter": "esbenp.prettier-vscode" // }, // "[javascript]": { // "editor.defaultFormatter": "esbenp.prettier-vscode" // }, // "[typescriptreact]": { // "editor.defaultFormatter": "esbenp.prettier-vscode" // }, // "[scss]": { // "editor.defaultFormatter": "HookyQR.beautify" // }, // "[html]": { // "editor.defaultFormatter": "HookyQR.beautify" // }, "code-runner.runInTerminal": true, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "diffEditor.ignoreTrimWhitespace": false, "[html]": { "editor.defaultFormatter": "HookyQR.beautify" }, "window.zoomLevel": 2 // TODO Tree Setting // "todo-tree.regex.regex": "((//|#|<!--|;|/\\*|^)\\s*(@?)($TAGS):|^\\s*- \\[ \\])", // // INFO: (@?) 这里可添加一些特殊符号 // // "todo-tree.regex.regex": "(//|#|<!--|;|/\\*|^|^\\s*(-|\\d+.))\\s*", // // INFO: 忽略大小写 // "todo-tree.regex.regexCaseSensitive": false, // "todo-tree.tree.autoRefresh": true, // "todo-tree.general.tags": [ // "TODO:", // "HOTFIX:", // "BUGFIX", // "DONE:", // "NOTE:", // "INFO:", // "LINK_TO", // "TAG", // "N.B.", // "HACK", // "[ ]", // "[x]" // ], // "todo-tree.highlights.defaultHighlight": { // "gutterIcon": true // // "type": "text-and-comment" // }, // // "todo-tree.highlights.defaultHighlight": { // // "icon": "alert", // // "type": "text", // // "foreground": "red", // // "background": "white", // // "opacity": 50, // // "iconColour": "blue" // // }, // // icon: https://microsoft.github.io/vscode-codicons/dist/codicon.html // "todo-tree.highlights.customHighlight": { // "[ ]": { // "background": "#F44336" // }, // "[x]": { // "background": "#00de00" // }, // "TODO:": { // "foreground": "#fff", // "background": "#ffbd2a", // "iconColour": "#ffbd2a", // }, // "HOTFIX:": { // "foreground": "#fff", // "background": "#f06292", // "icon": "flame", // "iconColour": "#f06292" // }, // "DONE": { // "background": "#2BBE4E", // "icon": "issue-closed", // "rulerColour": "#2BBE4E", // "iconColour": "#2BBE4E" // }, // "INFO:": { // "foreground": "#fff", // "background": "#3f83f8", // "icon": "info", // "iconColour": "#3f83f8" // }, // "LINK_TO:": { // "foreground": "#fff", // "background": "#3f33f8", // "icon": "info", // "iconColour": "#3f33f8" // }, // "NOTE:": { // "foreground": "#fff", // "background": "#3f83f8", // "icon": "note", // "iconColour": "#3f83f8" // }, // "TAG": { // "foreground": "#fff", // "background": "#03A9F4", // "icon": "tag", // "rulerColour": "#03A9F4", // "iconColour": "#03A9F4", // "rulerLane": "full" // }, // "BUGFIX": { // "foreground": "#fff", // "background": "#ee3c2c", // "icon": "bug", // "rulerColour": "#ee3c2c", // "iconColour": "#ee3c2c", // "rulerLane": "full" // }, // "N.B.": { // "foreground": "#fff", // "background": "#ffbd2a", // "icon": "shield", // "rulerColour": "#ffbd2a", // "iconColour": "#ffbd2a", // "rulerLane": "full" // }, // "HACK": { // "foreground": "#fff", // "background": "#cb2431", // "icon": "thumbsdown", // "rulerColour": "#cb2431", // "iconColour": "#cb2431", // "rulerLane": "full" // } // } }
-
9.附录
■ 参考网址
VUE风格指南 https://cn.vuejs.org/v2/style-guide/
BEM官网 http://getbem.com/
Google代码风格 https://github.com/google/styleguide
ESlint 插件 https://cn.eslint.org/
VUEPress 文档生成 https://vuepress.vuejs.org/
更多推荐
所有评论(0)