开发规范
项目目录结构规范
.
├── README.md ------------------------ 说明文件
├── package.json ----------------------- 项目配置
├── vue.config.js ------------------------ webpack配置入口
├── public --------------------------------- 入口文件
├── ├── favicon.ico ---------------- 网页图标
├── └── index.html --------------- 入口页面
└── src ------------------------------------- 源码目录
├── apis --------------------------------- 网络请求与请求的所有接口(分模块)
├── ├── index.js ----------------- 引入所有api
├── ├── config.js ----------------- 网络请求设置
├── ├── setup.js ----------------- 封装的所有网络请求
├── └── modules/xx.js ------- 按模块划分api
├── assets ----------------------------- 项目资源文件目录(图片、字体等)
├── ├── images ------------------ 所有图片
├── ├── less ----------------------- 所有样式
├── ├── ├─ index.less ------------------- 所有样式引入入口
├── ├── ├─ common/_base ----------- 公共基础样式
├── ├── ├─ common/_common ------ 通用公共样式
├── ├── ├─ common/_components - 公共样式部件
├── ├── ├─ common/_iconfont -------- 公共icon
├── ├── ├─ common/_mixins ---------- 公共混入样式
├── ├── ├─ common/_resetElement- 重置elementUI样式
├── ├── └─ common/_theme ---------- 主题色配置
├── ├── svgs ---------------------- 所有svg图片
├── components ------------------- 业务模块集合目录(组件)
├── ├── index.js ----------------- 注册所有全局组件
├── router ---------------------------- 路由
├── store ------------------------------ vuex(分模块)
├── utils ------------------------------ 工具函数
├── ├── commonData ------- 挂载在$common上的数据
├── ├── directive --------------- 所有指令
├── ├── filter -------------------- 所有过滤器
├── └── veeValidate ----------- 表单校验配置
├── plugins -------------------------- 引入的插件自动生成的配置
├── views ---------------------------- 页面集合目录
├── ├── xx.vue -------------------- 页面
├── └── children -----------------拆分出的子页面
├── App.less ------------------------ 主样式
├── App.vue ------------------------ 主组件
└── main.js ------------------------- 项目级入口配置文件
VUE开发规范
重点注意
1. 总是用 key 配合 v-for,key最好是列表数据的主键或某个唯一的值,不要用index。
2. 永远不要把 v-if 和 v-for 同时用在同一个元素上
3. 为组件样式设置作用域,样式使用 scoped
特性,并且在样式中避免使用元素选择器。
在 scoped
样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的。
规范
1. 组件数据
// bad 不建议使用
export default {
data: {
foo: 'bar'
}
}
// good 建议使用
export default {
data () {
return {
foo: 'bar'
}
}
}
2. 单文件组件文件名称
单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是横线连接 (kebab-case)。
// bad 不建议使用
mycomponent.vue
myComponent.vue
// good 建议使用
my-component.vue
MyComponent.vue
// used 项目中统一使用
MyComponent.vue
3. 紧密耦合的组件名
和父组件紧密耦合的子组件应该以父组件名作为前缀命名。
// bad
components/
|- TodoList.vue
|- TodoItem.vue
└─ TodoButton.vue
// good
components/
|- TodoList.vue
|- TodoListItem.vue
└─ TodoListItemButton.vue
4. 组件名中的单词顺序
组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾。
// bad
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
└─ TermsCheckbox.vue
// good
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
└─ SettingsCheckboxLaunchOnStartup.vue
5. 自闭合组件
在单文件组件中没有内容的组件应该是自闭合的。
<!-- bad -->
<my-component></my-component>
<!-- good -->
<my-component />
6. Prop 名大小写
在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板中应该始终使用 kebab-case,但是为了开发方便搜索,项目中在模板中使用 camelCase。
// bad
export default {
props: {
'greeting-text': String
}
};
// good
export default {
props: {
greetingText: String
}
}
<!-- good -->
<welcome-message greeting-text="hi" />
// 或者
<welcome-message greetingText="hi" />
<!-- used -->
<welcome-message greetingText="hi" />
7. Props 换行
多个 Props 的元素应该分多行撰写,每个 Props 一行,闭合标签单起一行。
<!-- bad -->
<my-component foo="a" bar="b" baz="c" />
<!-- good -->
<my-component
foo="a"
bar="b"
baz="c"
/>
8. Prop 定义
Prop 定义应该尽量详细, 至少需要指定其类型。
// bad
export default {
props: {
'greeting-text': String
}
};
// good
export default {
props: {
greetingText: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
}
9. 指令缩写
指令缩写,用 :
表示 v-bind:
,用 @
表示 v-on:
<!-- bad -->
<input
v-bind:value="value"
v-on:input="onInput"
>
<!-- good -->
<input
:value="value"
@input="onInput"
>
10. Props 顺序
标签的 Props 应该有统一的顺序,依次为指令、属性和事件。
<my-component
v-if="if"
v-show="show"
v-model="value"
ref="ref"
slot="slotName"
:key="key"
:text="text"
@input="onInput"
@change="onChange"
/>
11. 组件选项的顺序
组件选项应该有统一的顺序。
export default {
name: '',
mixins: [],
components: {},
props: {},
computed: {},
watch: {},
beforeCreate () {},
created() {},
beforeMount () {},
mounted() {},
beforeUpdate () {},
updated () {},
activated () {},
deactivated () {},
beforeDestroy () {},
destroyed() {},
data() {},
methods: {}
};
12. 组件选项中的空行
组件选项较多时,建议在属性之间添加空行。
export default {
computed: {
formattedValue() {
// ...
},
styles() {
// ...
}
},
methods: {
onInput() {
// ...
},
onChange() {
// ...
}
}
};
13. 单文件组件顶级标签的顺序
单文件组件应该总是让顶级标签的顺序保持一致,且标签之间留有空行。
<template>
...
</template>
<script>
/* ... */
</script>
<style>
/* ... */
</style>
其他约定规范
1. 路由与views文件名对应,一级路由对应index.vue
http://localhost:8080/good/detail
views/Good
|- index.vue
|- Detail.vue
└─ children/GoodItem.vue
2. 公共可复用的组件统一放在components
文件中
3. 公共样式以g-
开头
4. 单行代码不能超过120个字符,应合理换行
Git规范
1. Git Commit Message 规范
我们可以看下 angular 在github上的提交记录,如下是部分摘录:
从上图的提交记录可以看出,angular的开发者是比较注重Git提交信息规范的(Angular 规范)。一个精心提炼的提交记录可以向其他开发人员(包括他们自己)传达更改上下文的信息,这样非常有助于一个项目的可维护性,因此,考虑如何构建一个优秀的提交记录是非常值得去做的事情。
1.1 约定格式
<type>: <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
Message Header
消息头是一行精炼描述提交变化的信息。它包含 和 。
必选, 用于说明commit的类别,只允许使用下面几个标识:
动词 | 说明 |
---|---|
add | 创建功能, 例如:功能特性, 测试用例, 库依赖等 |
del | 删除功能, 例如:功能特性, 测试用例, 库依赖等 |
fix | 解决问题, 例如:错误异常等 |
bump | 修改某个版本号, 例如:依赖库的版本号等 |
conf | 配置文件修改 |
refactor | 必须进行重构的代码 |
reformat | 代码格式化 |
optimize | 代码性能优化 |
doc | 文档构建与修改 |
start | 开始做某事,比如创建分支等 |
end | 结束做某事,比如删除分支等 |
必选,用精炼的信息来描述更改的变化,有以下一条规则:
- 主题说明限制在72个字符以内。72个字符并不是一个严格的限制,只是一个经验法则。保持这样的主题行长度可以确保它们是可读的,并迫使开发者思考一下最简洁的方式来解释正在发生的事情。
Message Body
可选的,用于对本次提交进行详细说明。有以下两条规则:
- 可以分成多行,但是任何一行都不得超过72个字符。这是为了避免自动换行影响美观。
- 在Body 和 Header之间必须用空行分开
经验法则:
- Git配置编辑器。通常使用 $git -m 选项编写带有详细内容的提交消息时并不太方便。所以最好在适当的文本编辑器中编写提交信息。如果还没有在命令行中设置一个与Git一起使用的编辑器,请进行对应的配置。
- 内容中要解释what、why、how。在大多数情况下,可以忽略关于如何进行更改的细节。在这方面,代码通常是自解释的。只要把注意力集中在未作出改变之前它有什么问题,为什么采用这种方式来解决它以及作出改变之后它是如何运作的。这样我们花点时间在这里提供一个上下文,其实是可以为同事(包括自己)节省不少时间的。
Message Footer
1.2 示例
feat: onUrlChange event (popstate/hashchange/polling)
Added new event to $browser:
- forward popstate event if available
- forward hashchange event if popstate not available
- do polling when neither popstate nor hashchange available
Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
2. 如何管理分支
Git 是目前最流行的源代码管理工具。和软件开发中的其他实践一样,Git 分支管理并没有普遍适用的最佳做法,而只有对每个团队和项目而言最适合的做法。在我们内部,只使用四种分支:master分支、feature分支、release分支 和 hotfix分支。这些分支的作用和生命周期各不相同。master分支是已发布生产的稳定版本,生命周期是无限的,可读不可写。其它分支都是用于特定用途的分支,生命周期是有限的,可读可写,并受严格的规则约束,即可以从哪些原始分支checkout,最终必须合并到哪些分支。
分支类型 | 命名规范 | 创建自 | 合并到 | 说明 |
---|---|---|---|---|
feature | feature-* | master | release | 新功能 |
release | release | master | master | 一次新版本的发布 |
hotfix | hotfix-* | master | master | 生产环境中发现的紧急Bug的修复 |
**
**
规则一,开始工作前,从主干创建特性分支
每当开始一件新的功能开发的时候,从代表最新已发布版本的master主干上创建一个通常以feature-
前缀命名的特性分支,然后在这个分支上提交代码修改。也就是说,每个工作项(可以是一个人完成,或是多个人协作完成)对应一个特性分支,所有的修改都不允许直接提交到主干。
创建特性分支
$ git checkout -b feature-myfeature master
Switched to a new branch "feature-myfeature"
规则二,通过合并特性分支,形成发布分支。
当我们feature分支在开发环境联调完毕,我们可以从master主干上拉出一条新分支release分支,将所有本次要集成或发布的特性分支依次合并过去,从而得到发布分支。发布分支通常以release
命名。
创建release分支
$ git checkout -b release master
Switched to a new branch "release"
合并特性分支
$ git merge --no-ff feature_myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git push origin release
特性合并到release分支后,提测的方式是在发布分支上打标签号提测。标签号规范如下
发布分支 | 格式 | 说明 |
---|---|---|
release | release-fe(server)-*-YYMMDDNo | YYMMDD表年月日,fe(server)表前后端,*表示功能说明,No表递增自然数 |
打标签提测
$ git tag release-server-featureDesc-2020040101
$ git push origin release-server-featureDesc-2020040101
hotfix分支
与release分支非常相似的是hotfix分支,因为它们都意味着一个新的产品版本,但是hotfix分支是计划外的,是由于生产问题突发导致的。
创建hotfix分支
$ git checkout -b hotfix-featureDesc master
Switched to a new branch "hotfix-featureDesc"
**合并hotfix分支
**
在hotfix分支上修复完Bug之后,同样是打标签进行提测。标签号规范如下:
发布分支 | 格式 | 说明 |
---|---|---|
hotfix | hotfix-fe(server)-*-YYMMDDNo | YYMMDD表年月日,fe(server)表前后端,*表示功能说明,No表递增自然数 |
打标签提测
$ git tag hotfix-server-featureDesc-2020040101
$ git push origin hotfix-server-featureDesc-2020040101
说明
提测时,若当前存在release分支在测试中,务必将修复完的功能也合并到对应的release分支上。
**
**
规则三,发布到线上正式环境后,合并相应的发布Tag号到master主干,同时删除该发布分支以及关联的特性分支(管理员权限)
当一条发布分支上的流水线完成了一次线上正式环境的部署,就意味着相应的功能真正的发布了,此时应该将这条发布分支合并到主干。为了避免在代码仓库里堆积大量历史上的特性分支,还应该清理掉已经上线部分特性分支。
合并发布分支的标签
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-server-featureDesc-2020040101
Updating ea1b82a..05e9599
(Summary of changes)
$ git push
3. 常见问题
- 问:feature分支提测前应该做哪些操作?
首先必须保证功能联调正常完成,然后从最新的master主干上创建一个release分支(创建前要保证远程最新master代码已拉取到本地),最后将要发布的feature分支合并到release分支上推送到远程,再打Tag进行提测。
- 问:如果需要进行多分支并行测试如何做?
release分支本身可以很灵活,通过创建*release_1
、release_2
*来区分两套环境。但是多套环境本身也带来了复杂性,在这个过程需要格外注意要发布版本的代码是否和最新的master代码是否一致。
- 问:版本超前发布如何处理?
有时版本发布可能不在我们的预期中需要超前发布,这时我们需要删除存在的release分支(后期如果要继续测试我们中断的版本可以通过对应的最新tag号来回溯之前的快照版本),从master分支创建新的release分支,将我们要超前发布的版本功能合并到新的release分支上。
- 问:feature分支、release分支何时删除?
feature分支和release分支都是在我们功能正常发布之后并合并到master之后进行删除,通常由我们合并代码的管理员来进行删除。
- 问:新版本上线,以什么方式将新功能的代码合并到master?
新版本上线后,在生产环境安全观察之后,我们要把release上的最新版本的Tag号合并到master。
- 问:版本回滚如何处理?
在新版本上线之后我们是会有一个生产环境安全观察的过程,正常之后我们才将功能合并到master。如果是在合并master之前出现版本回滚,那么我们可以进行再修复之后再发布。如果是在合并master之后出现版本回滚,那么我们是不推荐直接在master分支上进行代码回滚发布的,而是运维同学将我们的发布镜像回滚到之前的正常镜像,而我们再从master分支上创建一个hotfix分支进行热修复。
README规范
前言
每个项目的readme是必要的且要经常维护的,写readme的目的是能简要的描述该项目的信息,让读者快速了解这个项目。
一个合格的readme文件应至少包含以下五个部分:项目标题及说明、有哪些功能、如何运行、项目结构、常见问题说明
模版
# operation-demo
> 后台管理系统模板 [预览](https://fifteen718.github.io/operation-preview/#/login)
## 功能简述
1. 主界面包含: 登录页面;首页;用户管理(用户资产查询、用户日志查询、用户管理);系统管理(分组权限管理、APP版本管理、后台账号管理、权限分配、修改密码)。
2. 主功能包含: 本地mock数据;登录跳转;导航栏菜单伸缩;表单校验中文提示;列表查询的常用布局;弹窗的父子组件传值;树组件、嵌套列表的使用。
## 安装预览
```bash
# 安装依赖
npm i || yarn || cnpm
# 启动本地调试
yarn start
# 打包压缩
yarn build
# eslint格式校验
yarn lint
```
## 项目结构
```
.
├── README.md ------------------------ 说明文件
├── package.json ----------------------- 项目配置
├── vue.config.js ------------------------ webpack配置入口
├── public --------------------------------- 入口文件
├── ├── favicon.ico ---------------- 网页图标
├── └── index.html --------------- 入口页面
└── src ------------------------------------- 源码目录
├── apis --------------------------------- 网络请求与请求的所有接口(分模块)
├── ├── index.js ----------------- 引入所有api
├── ├── config.js ----------------- 网络请求设置
├── ├── setup.js ----------------- 封装的所有网络请求
├── └── modules/xx.js ------- 按模块划分api
├── assets ----------------------------- 项目资源文件目录(图片、字体等)
├── ├── images ------------------ 所有图片
├── ├── less ----------------------- 所有样式
├── ├── ├─ index.less ------------------- 所有样式引入入口
├── ├── ├─ common/_base ----------- 公共基础样式
├── ├── ├─ common/_common ------ 通用公共样式
├── ├── ├─ common/_components - 公共样式部件
├── ├── ├─ common/_iconfont -------- 公共icon
├── ├── ├─ common/_mixins ---------- 公共混入样式
├── ├── ├─ common/_resetElement- 重置elementUI样式
├── ├── └─ common/_theme ---------- 主题色配置
├── ├── svgs ---------------------- 所有svg图片
├── components ------------------- 业务模块集合目录(组件)
├── ├── index.js ----------------- 注册所有全局组件
├── router ---------------------------- 路由
├── store ------------------------------ vuex(分模块)
├── utils ------------------------------ 工具函数
├── ├── commonData ------- 挂载在$common上的数据
├── ├── directive --------------- 所有指令
├── ├── filter -------------------- 所有过滤器
├── └── veeValidate ----------- 表单校验配置
├── plugins -------------------------- 引入的插件自动生成的配置
├── views ---------------------------- 页面集合目录
├── ├── xx.vue -------------------- 页面
├── └── children -----------------拆分出的子页面
├── App.less ------------------------ 主样式
├── App.vue ------------------------ 主组件
└── main.js ------------------------- 项目级入口配置文件
```
## 常见问题说明
1. 如果`vee-validate`在项目运行时报错,请重新安装旧版本,操作如下:
* `yarn remove vee-validate`
* 或 `yarn add vee-validate@2.0.0-rc.25`
2. 路由模式变更,操作如下:
* router.js -> 路由切换history模式去URL中的#号,`mode: 'history'`
* vue.config.js -> 注释掉`baseUrl: process.env.NODE_ENV === 'production' ? './' : '/'`即可
注释规范
data属性说明
1. 单行属性,注释写在行尾
good
activeName: 'actList', // 活动名称
bad:
// 活动名称
activeName: 'actList',
2. 多行属性,注释写在行上
good:
// 表格配置
tableConfig: [
{
name: "SKU",
val: "product_model"
}, {
name: "活动已售",
val: "sold"
}, {
name: "待拼成订单",
val: "pending"
}
]
bad:
tableConfig: [ // 表格配置
{
name: "SKU",
val: "product_model"
}, {
name: "活动已售",
val: "sold"
}, {
name: "待拼成订单",
val: "pending"
}
]
3. Array>Object结构的,只注释第一个对象内部属性即可
good:
tableConfig: [
{
name: "SKU", // 表头名字
val: "product_model" // 对应的接口字
}, {
name: "活动已售",
val: "sold"
}, {
name: "待拼成订单",
val: "pending"
}
]
bad:
tableConfig: [
{
name: "SKU", // 表头名字
val: "product_model" // 对应的接口字
}, {
name: "活动已售", // 表头名字
val: "sold" // 对应的接口字
}, {
name: "待拼成订单", // 表头名字
val: "pending" // 对应的接口字
}
]
4. Object>简单类型的,每一个属性都进行说明
good:
params: {
email: null, // 邮箱
name: null // 名称
}
bad:
params: {
// 邮箱
email: null,
// 名称
name: null
}
props、computed、watch说明
统一采用行上注释
methods说明
需包含方法描述、参数说明、返回值说明
-
方法描述: 以@description开头,后面跟方法描述
-
参数说明: 以@param开头,后面跟{数据类型}和参数说明
-
- 参数可以是多种数据类型时,以“,”分隔,eg:{String, Number, Object}
- 可以是任意数据类型时,用“”表示,eg:{}
-
返回值说明; 以@return开头,后面跟{数据类型}和返回值说明
good
/**
* @description 获取指定cookie
* @param {String} cName 指定cookie的key名
* @return {String} 返回cookie的value,没找到返回''
*/
function getCookie (cName) {
if (document.cookie.length > 0) {
let cStart = document.cookie.indexOf(cName + '=')
if (cStart !== -1) {
cStart = cStart + cName.length + 1
let cEnd = document.cookie.indexOf(';', cStart)
if (cEnd === -1) {
cEnd = document.cookie.length
}
return unescape(document.cookie.substring(cStart, cEnd)).replace(/"/g, '')
}
}
return ''
}
bad
other
CSS开发规范
关于开发方式
【旧的CSS开发方式】
定义类名(好烦躁,取什么名好呢) => 写样式(好烦躁,写来写去不还是那几个属性)=> 改样式(好烦躁,我好像改错地方了)
【新的CSS开发方式】
使用基础样式库,书写类名时自由组合,其他样式另写
优点:
- 避免写重复样式
- 修改样式时,只需更改类名,可减少浏览器重绘页面
关于基础样式库
【现状】
现阶段我们的UI界面还未高度统一,因此我们的基础样式只收集了最简单的一部分,存放于我们的开发模板中
【目录结构】
index.less ------------------ 所有样式引入入口
├─ common/_base ----------- 公共基础样式
├─ common/_common ------ 通用公共样式
├─ common/_components - 公共样式部件
├─ common/_iconfont -------- 公共icon
├─ common/_mixins ---------- 公共混入样式
├─ common/_resetElement- 重置elementUI样式
└─ common/_theme ---------- 主题色配置
【命名规范】
全局命名以 g
开头,-
连接
规则:g-<属性简写>-<属性值>
常见属性如margin、padding、color,使用简写:g-m-10
、g-pd-10
、g-c-666
【期望】
完善我们的基础样式库并托管在gitlab和npm上,跟随业务的不断成熟,最终实现0样式开发
CSS书写规范
采用stylelint-config-standard
标准,并使用stylelint做静态检查
【stylelint学习】腾讯云stylelint使用手册
【stylelint规则查询手册】stylelint
规则如下:
stylelint-config-recommended规则:
“use strict”;
module.exports = {
rules: {
“at-rule-no-unknown”: true, // 禁止使用未知的 at 规则
“block-no-empty”: true, // 禁止出现空块
“color-no-invalid-hex”: true, // 禁止使用无效的十六进制颜色
“comment-no-empty”: true, // 禁止空注释
“declaration-block-no-duplicate-properties”: [
true,
{
ignore: [“consecutive-duplicates-with-different-values”]
}
], // 在声明的块中中禁止出现重复的属性,不同值除外
“declaration-block-no-shorthand-property-overrides”: true, // 禁止缩写属性覆盖相关普通写法属性
“font-family-no-duplicate-names”: true, // 禁止使用重复的字体名称
“font-family-no-missing-generic-family-keyword”: true, // font-family缺少关键值
“function-calc-no-invalid”: true, // 禁止使用无效的 calc 函数
“function-calc-no-unspaced-operator”: true, // 禁止在 calc 函数内使用不加空格的操作符
“function-linear-gradient-no-nonstandard-direction”: true, // 禁止 linear-gradient() 中无效的方向值
“keyframe-declaration-no-important”: true, // 禁止在 keyframe 声明中使用 !important
“media-feature-name-no-unknown”: true, // 禁止使用未知的 media 特性名称
“no-descending-specificity”: true, // 禁止低优先级的选择器出现在高优先级的选择器之后
“no-duplicate-at-import-rules”: true, // 禁止重复引用样式表
“no-duplicate-selectors”: true, // 在一个样式表中禁止出现重复的选择器
“no-empty-source”: true, // 禁止空源
“no-extra-semicolons”: true, // 禁止多余的分号
“no-invalid-double-slash-comments”: true, // 禁用 CSS 不支持的双斜线注释
“property-no-unknown”: true, // 禁止使用未知属性
“selector-pseudo-class-no-unknown”: true, // 禁止使用未知的伪类选择器
“selector-pseudo-element-no-unknown”: true, // 禁止使用未知的伪元素
“selector-type-no-unknown”: true, // 禁用未知的类型选择器
“string-no-newline”: true, // 禁止在字符串中使用(非转义的)换行符
“unit-no-unknown”: true // 禁止使用未知单位
}
};
🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🇨🇳
stylelint-config-standard规则如下:
“use strict”
module.exports = {
“extends”: “stylelint-config-recommended”,
“rules”: {
“at-rule-empty-line-before”: [ “always”, {
except: [
“blockless-after-same-name-blockless”,
“first-nested”,
],
ignore: [“after-comment”],
} ], // 要求在 at 规则之前有空行
“at-rule-name-case”: “lower”, // 指定 at 规则名称的小写
“at-rule-name-space-after”: “always-single-line”, // 在单行声明块中,要求在 at 规则之后有一个空格
“at-rule-semicolon-newline-after”: “always”, // 要求在 at 规则的分号之后有一个换行符
“block-closing-brace-empty-line-before”: “never”, // 禁止在闭括号之前有空行
“block-closing-brace-newline-after”: “always”, // 在闭括号之后要求有一个换行符
“block-closing-brace-newline-before”: “always-multi-line”, // 在闭括号之前要求有一个换行符
“block-closing-brace-space-before”: “always-single-line”, // 在闭括号之前要求有一个空格
“block-opening-brace-newline-after”: “always-multi-line”,
“block-opening-brace-space-after”: “always-single-line”,
“block-opening-brace-space-before”: “always”,
“color-hex-case”: “lower”, // 指定十六进制颜色小写
“color-hex-length”: “short”, // 简写
“comment-empty-line-before”: [ “always”, {
except: [“first-nested”],
ignore: [“stylelint-commands”],
} ], // 要求在注释之前有空行
“comment-whitespace-inside”: “always”, // 要求在注释标签内有空白
“custom-property-empty-line-before”: [ “always”, {
except: [
“after-custom-property”,
“first-nested”,
],
ignore: [
“after-comment”,
“inside-single-line-block”,
],
} ], // 要求在自定义属性之前有一行空行
“declaration-bang-space-after”: “never”, // 在感叹号之后禁止有空白
“declaration-bang-space-before”: “always”, // 在感叹号之前要求有一个空格
“declaration-block-semicolon-newline-after”: “always-multi-line”, // 在声明块的分号之后要求有一个换行符
“declaration-block-semicolon-space-after”: “always-single-line”, // 在声明块的分号之后要求有一个空格
“declaration-block-semicolon-space-before”: “never”,
“declaration-block-single-line-max-declarations”: 1, // 限制单行声明块中声明的数量
“declaration-block-trailing-semicolon”: “always”, // 要求在声明块中使用拖尾分号
“declaration-colon-newline-after”: “always-multi-line”, // 在冒号之后要求有一个换行符
“declaration-colon-space-after”: “always-single-line”, // 在冒号之后要求有一个空格
“declaration-colon-space-before”: “never”, // 在冒号之前禁止一个空格
“declaration-empty-line-before”: [ “always”, {
except: [
“after-declaration”,
“first-nested”,
],
ignore: [
“after-comment”,
“inside-single-line-block”,
],
} ], // 要求在声明语句之前有空行
“function-comma-newline-after”: “always-multi-line”, // 在函数的逗号之后要求有一个换行符
“function-comma-space-after”: “always-single-line”,
“function-comma-space-before”: “never”,
“function-max-empty-lines”: 0,
“function-name-case”: “lower”,
“function-parentheses-newline-inside”: “always-multi-line”,
“function-parentheses-space-inside”: “never-single-line”,
“function-whitespace-after”: “always”,
“indentation”: 2, // 指定缩进
“length-zero-no-unit”: true, // 长度为0时,禁止使用单位
“max-empty-lines”: 1, // 限制值列表中相邻空行数量
“media-feature-colon-space-after”: “always”, // 媒体功能
“media-feature-colon-space-before”: “never”,
“media-feature-name-case”: “lower”,
“media-feature-parentheses-space-inside”: “never”,
“media-feature-range-operator-space-after”: “always”,
“media-feature-range-operator-space-before”: “always”,
“media-query-list-comma-newline-after”: “always-multi-line”,
“media-query-list-comma-space-after”: “always-single-line”,
“media-query-list-comma-space-before”: “never”,
“no-eol-whitespace”: true, // 禁止行尾空白
“no-missing-end-of-source-newline”: true, // 禁止缺少文件末尾的换行符
“number-leading-zero”: “always”, // 要求小于 1 的小数的前导 0
“number-no-trailing-zeros”: true, // 禁止数字中的拖尾 0
“property-case”: “lower”, // 指定属性的小写
“rule-empty-line-before”: [ “always-multi-line”, {
except: [“first-nested”],
ignore: [“after-comment”],
} ], // 要求在 at 规则之前有空行
“selector-attribute-brackets-space-inside”: “never”, // 选择器相关
“selector-attribute-operator-space-after”: “never”,
“selector-attribute-operator-space-before”: “never”,
“selector-combinator-space-after”: “always”,
“selector-combinator-space-before”: “always”,
“selector-descendant-combinator-no-non-space”: true,
“selector-list-comma-newline-after”: “always”,
“selector-list-comma-space-before”: “never”,
“selector-max-empty-lines”: 0,
“selector-pseudo-class-case”: “lower”,
“selector-pseudo-class-parentheses-space-inside”: “never”,
“selector-pseudo-element-case”: “lower”,
“selector-pseudo-element-colon-notation”: “double”,
“selector-type-case”: “lower”,
“unit-case”: “lower”, // 指定单位的小写
“value-keyword-case”: “lower”, // 指定关键字的值小写
“value-list-comma-newline-after”: “always-multi-line”, // 在值列表的逗号之后要求有一个换行符
“value-list-comma-space-after”: “always-single-line”, // 在值列表的逗号之后要求有一个空格
“value-list-comma-space-before”: “never”, // 在值列表的逗号之前禁止有空白
“value-list-max-empty-lines”: 0, // 限制值列表中相邻空行数量
},
}
🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🇨🇳
自定义规则
module.exports = {
extends: ‘stylelint-config-standard’,
rules: {
‘declaration-bang-space-before’: ‘never’, // 在感叹号之前不能有一个空格
indentation: 4, // 锁进4个单位
‘number-leading-zero’: ‘never’ // 要求小于 1 的小数的前导 0 省略
}
“selector-combinator-space-after”: “always”,
“selector-combinator-space-before”: “always”,
“selector-descendant-combinator-no-non-space”: true,
“selector-list-comma-newline-after”: “always”,
“selector-list-comma-space-before”: “never”,
“selector-max-empty-lines”: 0,
“selector-pseudo-class-case”: “lower”,
“selector-pseudo-class-parentheses-space-inside”: “never”,
“selector-pseudo-element-case”: “lower”,
“selector-pseudo-element-colon-notation”: “double”,
“selector-type-case”: “lower”,
“unit-case”: “lower”, // 指定单位的小写
“value-keyword-case”: “lower”, // 指定关键字的值小写
“value-list-comma-newline-after”: “always-multi-line”, // 在值列表的逗号之后要求有一个换行符
“value-list-comma-space-after”: “always-single-line”, // 在值列表的逗号之后要求有一个空格
“value-list-comma-space-before”: “never”, // 在值列表的逗号之前禁止有空白
“value-list-max-empty-lines”: 0, // 限制值列表中相邻空行数量
},
}
🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🚛🇨🇳
自定义规则
module.exports = {
extends: ‘stylelint-config-standard’,
rules: {
‘declaration-bang-space-before’: ‘never’, // 在感叹号之前不能有一个空格
indentation: 4, // 锁进4个单位
‘number-leading-zero’: ‘never’ // 要求小于 1 的小数的前导 0 省略
}
}