做者:JowayYoung
仓库:Github、CodePen
博客:官网、掘金、思否、知乎
公众号:IQ前端
特别声明:原创不易,未经受权不得转载或抄袭,如需转载可联系笔者受权css
大部分前端项目都配置Stylelint
、Eslint
、Tslint
和Prettier
四大前端代码校验工具。代码校验工具如下简称Lint
,为了解决代码不严谨,经过预设规则校验代码,检测其是否存在错误/漏洞
,并对错误/漏洞
提示修复方案并尽量依据修复方案格式化出正确代码。该功能称为格式化代码,基本上全部编辑器都需配置该功能。html
Lint
其实就是编辑器里运行的一个脚本进程,将代码解析成抽象语法树
,遍历抽象语法树
并经过预设规则作一些判断和修改,再将新的抽象语法树
转换成正确代码。整个校验过程都跟抽象语法树
相关,若暂未接触过抽象语法树
,可阅读babel源码
或eslint源码
了解其工做原理。前端
开发过程当中启用Lint
能带来如下好处。vue
团队编码规范
,让新旧组员编码习惯获得一致提高团队编码风格
,让预设规则符合新旧组员心理预期可维护性
和可接入性
,让新组员能快速适应项目的架构与需求无用代码
、重复代码
、错误代码
和漏洞代码
的产生概率千万不能自私node
有些同窗可能一时适应不了Lint
带来的强制性操做,会在本身编辑器里关闭项目全部校验功能,这种自私行为会带来很严重的后果。react
若上传无任何校验痕迹的代码块,当其余组员将该代码块更新合并到原有代码上时,因为编辑器一直配置着团队编码规范
,致使被拉下来的代码块立马报错甚至产生冲突。git
上述状况会让其余组员花费更多时间解决由于你不遵照规矩而带来的问题,还浪费团队为了研究如何让总体编码风格更适合组员的精力。github
这种自私行为不可取,若团队无任何编码规范可随意编码,若已承认团队编码规范
那就努力遵照,不给团队带来麻烦。web
本文着重讲解一键格式化代码的部署,像Lint
经常使用配置就不会讲解,毕竟百度谷歌一搜一大堆。这个一键固然是ctrl+s
或cmd+s
保存文件啦。在保存文件时触发Lint
自动格式化代码,这个操做固然不能100%
保证将代码格式化出最正确代码,而是尽量依据修复方案格式化出正确代码。言下之意就是可能存在部分代码格式化失败,但将鼠标移至红色下划线上会提示修复方案,此时可依据修复方案自行修正代码。typescript
为什么写下本文?笔者有着严谨的代码逻辑和优雅的编码风格,因此特别喜欢格式化代码。然而又不想为每一个项目配置Lint
,这些重复无脑的复制粘贴让笔者很反感,因此笔者只想一次配置全局运行Lint
,这样就无需为每一个项目配置Lint
。在大量百度谷歌都未能搜到一篇相关文章(搜到的所有文章都是单独为一个项目配置,害
),笔者就花了半年多时间探讨出本方案,真正作到一次配置全局运行。若使用本方案,相信能将全部项目的Stylelint
、Eslint
、Tslint
和Prettier
相关依赖和配置文件所有移除,使项目目录变得超级简洁,如同下图。
笔者选用VSCode
做为前端开发的编辑器,其余编辑器不是性能差就是配置麻烦,因此通通放弃,只认VSCode
。
在此强调两个重要问题,这两个问题影响到后面可否成功部署VSCode
的一键格式化代码。
Tslint
官方已宣布废弃Tslint
,改用Eslint
代替其全部校验功能Eslint
部分配置与Prettier
部分配置存在冲突且互相影响,为了保证格式化性能就放弃接入Prettier
因此部署VSCode
的一键格式化代码只需安装Stylelint
和Eslint
两个插件。为了方便表述,统一如下名词。
VSCode插件
NPM依赖
前方高能,两大步骤就能为VSCode
部署一键格式化代码,请认真阅读喔!
安装依赖
为了搞清楚两个插件集成哪些NPM依赖
,如下区分安装stylelint
和eslint
及其相关依赖(看看便可,不要安装,重点在后头)。笔者有个习惯,就是喜欢将依赖更新到最新版本,在享受新功能的同时也顺便填坑。
# Stylelint
npm i -D stylelint stylelint-config-standard stylelint-order
复制代码
# Eslint
npm i -D eslint babel-eslint eslint-config-standard eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-react eslint-plugin-standard eslint-plugin-vue vue-eslint-parser
复制代码
# TypeScript Eslint
npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser typescript eslint-config-standard-with-typescript
复制代码
安装完成后需配置多份对应配置文件,CSS方面有css/scss/less/vue
文件,JS方面有js/ts/jsx/tsx/vue
文件。查看插件文档,发现Stylelint
只能在settings.json
上配置,而Eslint
可配置成多份对应配置文件,并在settings.json
上经过特定字段指定Eslint
配置文件路径。
settings.json是VSCode的配置文件,用户可经过插件暴露的字段自定义编辑器功能。
复制代码
因为配置文件太多很差管理,笔者开源了本身日常使用的配置文件集合,详情可查看vscode-lint。
js文件
jsx文件
vue文件
TypeScript
ts文件
tsx文件
vue文件
配置文件里的rule
可根据本身编码规范适当调整,在此不深刻讲解,毕竟简单得来谁都会。建议使用vscode-lint
,若校验规则不喜欢可自行调整。
如下会基于vscode-lint
部署VSCode
的一键格式化代码,找个目录经过git
克隆一份vscode-lint
,并安装其NPM依赖
。若使用vscode-lint
,上述依赖就不要安装了🙅。
git clone https://github.com/JowayYoung/vscode-lint.git
cd vscode-lint
npm i
复制代码
配置插件
VSCode
工具栏
的插件
,搜索并安装Stylelint
和Eslint
,安装完成后重启VSCode
文件 → 首选项 → 设置
,设置
里可选用户
和工做区
若大部分项目都是单一的React应用或Vue应用推荐使用全局配置
)设置
右上角中间图标打开设置(json)
,打开的对应文件是settings.json
(上述有说起)用户
选项下插入如下配置,遇到其余项目需覆盖配置时在工做区
选项下插入eslint.options.configFile
指定Eslint
配置文件路径VSCode
:为了保障每次修改配置后都能正常格式化代码,必须重启VSCode
{
"css.validate": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
"eslint.nodePath": "path/vscode-lint/node_modules",
"eslint.options": {
"configFile": "path/vscode-lint/eslintrc.js"
},
"less.validate": false,
"scss.validate": false,
"stylelint.configBasedir": "path/vscode-lint",
"stylelint.configOverrides": {
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-order"
],
"rules": {
"at-rule-empty-line-before": "never",
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"content",
"each",
"error",
"extend",
"for",
"function",
"if",
"include",
"mixin",
"return",
"while"
]
}
],
"color-hex-case": "lower",
"comment-empty-line-before": "never",
"declaration-colon-newline-after": null,
"declaration-empty-line-before": "never",
"function-linear-gradient-no-nonstandard-direction": null,
"indentation": "tab",
"no-descending-specificity": null,
"no-missing-end-of-source-newline": null,
"no-empty-source": null,
"number-leading-zero": "never",
"rule-empty-line-before": "never",
"order/order": [
"custom-properties",
"declarations"
],
"order/properties-order": [
// 布局属性
"display",
"visibility",
"overflow",
"overflow-x",
"overflow-y",
"overscroll-behavior",
"scroll-behavior",
"scroll-snap-type",
"scroll-snap-align",
// 布局属性:浮动
"float",
"clear",
// 布局属性:定位
"position",
"left",
"right",
"top",
"bottom",
"z-index",
// 布局属性:列表
"list-style",
"list-style-type",
"list-style-position",
"list-style-image",
// 布局属性:表格
"table-layout",
"border-collapse",
"border-spacing",
"caption-side",
"empty-cells",
// 布局属性:弹性
"flex-flow",
"flex-direction",
"flex-wrap",
"justify-content",
"align-content",
"align-items",
"align-self",
"flex",
"flex-grow",
"flex-shrink",
"flex-basis",
"order",
// 布局属性:多列
"columns",
"column-width",
"column-count",
"column-gap",
"column-rule",
"column-rule-width",
"column-rule-style",
"column-rule-color",
"column-span",
"column-fill",
"column-break-before",
"column-break-after",
"column-break-inside",
// 布局属性:格栅
"grid-columns",
"grid-rows",
// 尺寸属性
"box-sizing",
"margin",
"margin-left",
"margin-right",
"margin-top",
"margin-bottom",
"padding",
"padding-left",
"padding-right",
"padding-top",
"padding-bottom",
"border",
"border-width",
"border-style",
"border-color",
"border-colors",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"border-left-colors",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-right-colors",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-top-colors",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-bottom-colors",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-left-radius",
"border-bottom-right-radius",
"border-image",
"border-image-source",
"border-image-slice",
"border-image-width",
"border-image-outset",
"border-image-repeat",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
// 界面属性
"appearance",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"outline-radius",
"outline-radius-topleft",
"outline-radius-topright",
"outline-radius-bottomleft",
"outline-radius-bottomright",
"background",
"background-color",
"background-image",
"background-repeat",
"background-repeat-x",
"background-repeat-y",
"background-position",
"background-position-x",
"background-position-y",
"background-size",
"background-origin",
"background-clip",
"background-attachment",
"bakground-composite",
"mask",
"mask-mode",
"mask-image",
"mask-repeat",
"mask-repeat-x",
"mask-repeat-y",
"mask-position",
"mask-position-x",
"mask-position-y",
"mask-size",
"mask-origin",
"mask-clip",
"mask-attachment",
"mask-composite",
"mask-box-image",
"mask-box-image-source",
"mask-box-image-width",
"mask-box-image-outset",
"mask-box-image-repeat",
"mask-box-image-slice",
"box-shadow",
"box-reflect",
"filter",
"mix-blend-mode",
"opacity",
"object-fit",
"clip",
"clip-path",
"resize",
"zoom",
"cursor",
"pointer-events",
"user-modify",
"user-focus",
"user-input",
"user-select",
"user-drag",
// 文字属性
"line-height",
"line-clamp",
"vertical-align",
"direction",
"unicode-bidi",
"writing-mode",
"ime-mode",
"text-overflow",
"text-decoration",
"text-decoration-line",
"text-decoration-style",
"text-decoration-color",
"text-decoration-skip",
"text-underline-position",
"text-align",
"text-align-last",
"text-justify",
"text-indent",
"text-stroke",
"text-stroke-width",
"text-stroke-color",
"text-shadow",
"text-transform",
"text-size-adjust",
"src",
"font",
"font-family",
"font-style",
"font-stretch",
"font-weight",
"font-variant",
"font-size",
"font-size-adjust",
"color",
// 内容属性
"tab-size",
"overflow-wrap",
"word-wrap",
"word-break",
"word-spacing",
"letter-spacing",
"white-space",
"caret-color",
"quotes",
"content",
"content-visibility",
"counter-reset",
"counter-increment",
"page",
"page-break-before",
"page-break-after",
"page-break-inside",
// 交互属性
"will-change",
"perspective",
"perspective-origin",
"backface-visibility",
"transform",
"transform-origin",
"transform-style",
"transition",
"transition-property",
"transition-duration",
"transition-timing-function",
"transition-delay",
"animation",
"animation-name",
"animation-duration",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
"animation-play-state",
"animation-fill-mode",
// Webkit专有属性
"-webkit-overflow-scrolling",
"-webkit-box-orient",
"-webkit-line-clamp",
"-webkit-text-fill-color",
"-webkit-tap-highlight-color",
"-webkit-touch-callout",
"-webkit-font-smoothing",
"-moz-osx-font-smoothing"
]
}
}
}
复制代码
以上配置的path
为vscode-lint
所在的根目录,若刚才的vscode-lint
克隆到E:/Github
,那么path
就是E:/Github
。
上述步骤完成后就可愉快敲代码了。每次保存文件就会自动格式化CSS代码
或JS代码
,这个格式化代码不只会将代码按照规范整理
和排序
,甚至尽量依据修复方案格式化出正确代码。
这样就无需为每一个项目配置Lint
,将全部项目的Stylelint
、Eslint
、Tslint
和Prettier
相关依赖和配置文件所有移除,使项目目录变得超级简洁。
css/scss/less/vue文件
js/ts/jsx/tsx/vue文件
不少同窗反映eslint v6+
在VSCode
上失效,最高版本只能控制在v5.16.0
。其实这自己就是配置问题,跟版本无关。vscode-lint
的eslint
使用v7
照样能使用Eslint
,只要配置正确就能正常使用。
上述安装行为使用了NPM
,那么settings.json
的eslint.packageManager
必须配置为npm
(小写),但最新版本Eslint
已默认此项,因此无需配置。若上述安装行为变成yarn install
,那么必须在settings.json
里添加如下配置。
{
"eslint.packageManager": "yarn"
}
复制代码
这个配置就是解决该问题的关键了。
首次安装Eslint
可能会在js/ts/jsx/tsx/vue
文件里看到如下警告。
Eslint is disabled since its execution has not been approved or denied yet. Use the light bulb menu to open the approval dialog.
复制代码
说明Eslint
被禁用了,虽然配置里无明确的禁用字段,但仍是被禁用了。此时移步到VSCode
右下角的工具栏,会看到禁用图标+ESLINT
的标红按钮,单击它会弹出一个弹框,选择Allow Everywhere
就能启用Eslint
全部校验功能。
总体过程看似简单,其实笔者这半年填了不少坑才有了vscode-lint
,中间已省略了不少未记录的问题,这些疑问不重要却影响到不少地方。相信本文能让不少同窗体验VSCode
一键格式化代码所带来的快感,最关键的部分仍是无需为每一个项目配置Lint
,这省下多少时间和精力呀!以为牛逼给vscode-lint点个Star吧!
回看笔者往期高赞文章,也许能收获更多喔!
4200+
点赞量,15.6w+
阅读量4300+
点赞量,13w+
阅读量3300+
点赞量,4.5w+
阅读量1600+
点赞量,5w+
阅读量700+
点赞量,2.3w+
阅读量700+
点赞量,1.8w+
阅读量500+
点赞量,1.6w+
阅读量❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创做更多高质量文章
关注公众号IQ前端
,一个专一于CSS/JS开发技巧的前端公众号,更多前端小干货等着你喔
资料
免费领取学习资料进群
拉你进技术交流群IQ前端
,更多CSS/JS开发技巧只在公众号推送