1.TSLint 和 ESLint 是源码怎么融合在一起的
2.Eslint 的实现原理,其实挺简单
3.vue3-element-adminESLint+Prettier+Stylelint+EditorConfig 约束和统一前端代码规范
4.ESLint 的分析 parser 是个什么东西
5.Webpack入门到精通 五(常用配置)
TSLint 和 ESLint 是怎么融合在一起的
Eslint 能够对 JavaScript 代码进行静态检查,涵盖逻辑错误和代码格式问题。源码其工作原理是分析将代码解析成抽象语法树(AST),然后基于 AST 检测问题。源码
同样,分析lean源码备份Tslint 也是源码一款静态检查工具,用于检测 TypeScript 代码中的分析逻辑错误和代码格式问题,其原理也是源码基于 AST。
既然两者都基于 AST 且功能相似,分析为何不将它们合并呢?
最终,源码Tslint 被整合进了 Eslint,分析Tslint 被标记为废弃。源码
然而,分析两者毕竟基于不同的源码 AST,且 Tslint 中包含一些类型检查的逻辑,这是 Eslint 所不支持的。那么,它们是如何融合的呢?接下来,我们一起来探究。
不同的 AST
Eslint 使用 espree 作为自己的解析器,并生成相应的 AST。
Typescript 和 Babel 也都有各自的解析器和相应的 AST。
这些 AST 之间存在怎样的关系呢?
最早的解析器是 esprima,它参考了 Mozilla 浏览器 SpiderMonkey 引擎的 AST 标准,并进行了扩充,形成了 estree 标准。
后续的许多解析器都是对 estree 标准的实现和扩展,如 esprima、espree、babel parser(babylon)、acorn 等。
当然,也有不是 estree 标准的,如 typescript、小白主页锁定源码terser 等的解析器。
它们之间的关系如图所示:
esprima 和 acorn 都是 estree 标准的实现,而 acorn 支持插件机制来扩充语法,因此 espree 和 babel parser 是直接基于 acorn 实现的。
terser、typescript 等则是另一套。
因此,对于 JavaScript 的 AST,我们可以简单划分为两类:estree 系列、非 estree 系列。
可以使用 astexplorer.net 工具来可视化地查看不同解析器产生的 AST。
espree 就是 Eslint 自己实现的解析器,但它主要进行代码的逻辑和格式的静态检查,在新语法的实现进度上不如 babel parser。因此,Eslint 支持解析器的切换,可以在配置不同的解析器来解析代码。
配置文件中可以配置不同的解析器,并通过 parserOptions 来配置解析选项。
下面分别讲解 Eslint、typescript、babel、vue 等的解析器如何在 Eslint 中使用:
而且,在单文件组件中的 JS 部分,还可以分别指定不同的解析器。
感觉有点晕吗?typescript、babel、vue 等的解析器都有相应的用于 Eslint 的版本。其实想想也很正常,因为 lint 是基于 AST 的,如果不能解析,那么如何进行 lint,所以需要支持解析器的扩展和切换。
但是仿个性网源码,解析器之后的 AST 可能不同,那么 lint 的规则实现也不同。为了复用规则,大家还是尽量往 estree 标准上靠比较好。
Tslint 和 Eslint 的融合也是这样的思路,下面我们来详细了解一下。
Tslint 融合进 Eslint
Tslint 是一个独立的工具,基于 TypeScript 的解析器来解析代码,并实现了基于该 AST 的一系列规则。
如果要融合进 Eslint,那么如何融合呢?主要考虑的是 AST 如何融合,因为规则是基于 AST 的。
例如,const a = 1; 这段代码,estree 系列的 AST 是这样的:
而 TypeScript 的 AST 是这样的:
由于 AST 不同,那么基于 AST 的规则肯定也要有不同的实现。
如何融合呢?转换!把一种 AST 转成另一种 AST 就行了。
没错,@typescript-eslint/parser 中确实也是这么做的,它把 TypeScript 的 AST 转换成 estree 的 AST(当然,对于类型部分,estree 中没有,就保留了该 AST,但加上了 TS 前缀)。这样,就能够用 Eslint 的规则来检查 TypeScript 代码中的问题。
下面简单看一下 @typescript-eslint/parser 的源码:
我简化了一下,是这样的:
首先通过 TypeScript 的解析器将源码解析成 AST,然后转换成 estree 的,并记录了 estree node 和 TypeScript node 的映射关系,通过两个 map 来保存。
具体的转换过程,其实就是彩虹空间业务源码遍历 TypeScript 的 AST,然后创建新的 estree 的 AST。
其中,对于 estree 中没有的类型相关的 AST,则直接复制,并在 AST 名字前加个 TS。
这样,就把 TypeScript 解析器产生的 AST 转成了 estree 的。
既然 AST 统一了,那么 Eslint 的规则就可以用来 lint TypeScript 代码了。
但是对于一些类型的部分,还是需要用 TypeScript 的 API 来检查 TypeScript 的 AST 怎么办呢?
还记得我们保存了两个 map 吗?estree node 到 TypeScript node 的 map,还有反过来的 map。这样,需要用到 TypeScript 的 AST 的时候,再映射回去就行了:
Eslint 的自定义解析器的返回结果中,除了有 ast,还支持返回 services,这是用于放置一些其他信息的,比如这里用到的 map,还有 TypeScript 的 program 的 API(比如 program.getTypeChecker 这种)。需要的时候就可以从 estree 的 ast 再映射回 TypeScript 的 ast 了。
通过把 TypeScript AST 映射成 estree AST,达到了复用 Eslint 规则的目的,并保存了节点映射关系和一些操作 TypeScript AST 的 API,可以基于这些单独做 TypeScript 相关的 lint。完美地融合到了一起。
可以把这种融合用“求同存异”来总结:
总结
JavaScript 有不同的解析器,分为 estree 系列、非 estree 系列:
Eslint 支持解析器的切换,可以在 babel parser、vue template parser、typescript 和 espree 中切换,当然也可以扩展其他解析器。
Tslint 是广告墙网站源码一个基于 TypeScript 解析的独立工具。它和 Eslint 都是基于 AST 检查代码中逻辑和格式错误的工具,后来进行了融合。
为了复用基于 estree 的一些规则,@typescript-eslint/parser 把 TypeScript node 转成了 estree node,但依然保留了映射关系和一些操作 TypeScript ast 的 API。
这样基于 estree AST 的规则可以正常运行,基于 TypeScript AST 的规则也可以映射回原来的 TypeScript node 然后运行。
通过这种方式,完美地把 Eslint 和 Tslint 融合在一起。还是挺巧妙的。
Eslint 的实现原理,其实挺简单
Eslint 实现原理详解
Eslint 是一款流行的代码检查工具,它能够帮助开发者在编写代码的过程中发现并修复潜在的错误和不规范的代码风格。本文将深入探讨 Eslint 的实现原理,帮助你更好地理解其工作方式。
Eslint 的核心是 Linter 类,它提供了主要的 API,包括 SourceCode、Parser 和 Rule。SourceCode 代表抽象语法树(AST),Parser 是将源代码解析为 AST 的工具,Rule 则是用于检查和修复 AST 的规则。
Linter 的主要功能在 verify 和 verifyAndFix 方法中实现。当调用 --fix 或者配置文件设置 fix: true 时,会执行 verifyAndFix,用于检查并修复代码。否则,执行 verify 进行代码检查。
理解 Linter 的实现关键在于解析器(Parser)的选择与使用。默认使用 Eslint 自带的 espree,但也可以通过配置切换为其他解析器,如 @eslint/babel-parser 或 @typescript/eslint-parser。
在解析器确定后,源代码被解析为 AST,然后通过 SourceCode 封装。接下来,通过调用 runRules 方法,使用注册的规则对 AST 进行检查。runRules 遍历 AST,触发相应的事件,规则监听这些事件以执行检查逻辑。
规则注册与监听机制使得 Eslint 能够在遍历 AST 的过程中,执行各种检查任务。通过上下文(Context)传递信息,如 scope 和 settings,规则可以根据需要获取额外的细节。
检查结果以 lintingProblems 形式呈现,包括问题的起始和结束位置,以及相应的修复建议。修复实现为字符串替换操作,针对 AST 的范围进行替换,以自动修复代码问题。
此外,Eslint 支持预处理(Preprocess)和后处理(Postprocess),用于在检查前或后进行额外处理。这些功能通过配置文件中的注释指令(Comment Directives)实现,允许开发者自定义过滤规则。
为了在命令行环境下使用 Eslint,还引入了 CLIEngine 类,它负责解析命令行参数、文件读写等操作。最终,Eslint 提供了一个简洁的门面(EsLint 类),隐藏了不必要的细节,使得用户能够方便地使用 Eslint。
总结,Eslint 的实现原理基于 AST 的代码检查和字符串替换实现自动修复。通过解析器、规则注册、事件监听、问题收集与修复,以及预处理与后处理,Eslint 提供了一个高效、灵活的代码检查框架。掌握这些原理有助于开发者更深入地理解 Eslint 的工作机制,从而更好地利用它提高代码质量和开发效率。
vue3-element-adminESLint+Prettier+Stylelint+EditorConfig 约束和统一前端代码规范
vue3-element-admin 通过集成ESLint、Prettier、Stylelint和EditorConfig,确保前端代码的全面规范。这些工具分别负责代码一致性、格式化、CSS规范检查和跨编辑器编码风格统一。
首先,ESLint作为JavaScript/TS代码的检查工具,可通过安装VSCode插件并配置.eslintrc.cjs文件,确保代码质量。在默认配置中,需更换为vue-eslint-parser,以避免解析错误。
接下来,Prettier用于自动格式化代码,安装插件后,通过.prettierignore文件指定需要忽略的文件。在package.json中添加prettier指令以启动格式化和验证。
Stylelint专注于CSS/SCSS规范检测,尽管它不再是代码格式化的首选(Prettier更适合)。安装插件后,配置.stylelintrc.cjs并创建.stylelintignore文件,通过package.json指令执行验证。
EditorConfig确保不同IDE间的编码一致性,安装VSCode插件并创建.editorconfig文件,设置项目源码中的统一编码规则。项目的完整代码可在此处获取,如有疑问,可通过项目提供的交流渠道寻求帮助。
ESLint 的 parser 是个什么东西
ESLint是一个代码质量检查工具,其功能在于检测JavaScript代码中的问题并提供反馈。在执行代码检查时,需要有一个解析器,该解析器的职责是将开发者编写的JavaScript代码转化为AST(抽象语法树)形式,以便ESLint能够理解和进行检查。
AST是一种表示代码结构和逻辑的树形数据结构,ESTree是AST的一种特定规范,而ESLint默认采用的是ESTree规范来解析和验证代码。这意味着,即使代码使用了ES6及更高版本的语法,ESLint也能将其转换为ESTree形式进行检查。
对于一些特定的JavaScript转换工具,如@babel/eslint-parser和@babel/eslint-plugin,它们允许ESLint在经过Babel转换的源代码上运行,确保在不同版本的JavaScript和ESM模块中保持代码一致性。
在使用Babel进行代码转换时,Babel将代码转换为AST,而@babel/eslint-parser则进一步将这个AST转换为ESLint能够理解的ESTree格式,这样ESLint就可以进行语法检查和代码规范验证。
然而,ESLint的核心规则通常只支持最新的ECMAScript标准,而Babel的实验性特性或非标准特性(如Flow或TypeScript类型)则不被支持。为了解决这个问题,可以使用@babel/eslint-plugin,它提供了一套兼容Babel转换语法的规则集,从而在使用了Babel转换的代码中也能正常运行ESLint。
需要注意的是,虽然ESLint默认解析器和核心规则不支持实验性语法,但通过使用特定的解析器,如@babel/eslint-parser,可以实现对Babel转换代码的检查。在使用这些解析器时,需要结合Babel的转换功能,以确保代码的正确性和一致性。
在使用ESLint与Typescript结合时,会发现两者之间的AST格式存在差异,因为ESLint的默认解析器(Espree)和Typescript的解析器生成的AST并不完全兼容。为了实现跨语言的代码检查,可以使用@typescript-eslint解析器,它旨在兼容ESLint和Typescript的AST格式,提供更好的集成体验。
考虑到TSLint(基于Typescript解析器的代码检查工具)的逐步废弃,开发者更推荐使用@typescript-eslint作为ESLint在Typescript环境下的解析器。与TSLint相比,@typescript-eslint提供了更全面的规则集和更好的与ESLint的集成,从而使得在使用Typescript的项目中进行代码检查变得更加高效和简单。
在处理Typescript项目时,需要注意的是,由于Typescript编译器和Babel的转换器可能不兼容某些语言特性,因此在使用ESLint进行代码检查时,可能出现一些误报或兼容性问题。为了解决这些问题,可以使用@typescript-eslint/parser和对应的规则集,确保在使用了Babel进行代码转换的情况下,ESLint能够正确地检查代码并提供有用的反馈。
对于Vue项目,官方推荐使用eslint-plugin-vue插件,它提供了一个专门的解析器(vue-eslint-parser)和规则集(eslint.vuejs.org/rules/),用于检查Vue单文件组件中的script部分。通过配置parserOptions.parser参数,可以指定使用不同的解析器来满足特定的代码检查需求。
Webpack入门到精通 五(常用配置)
为更好的阅读体验请移步掘金
初始化项目
在package.json中添加
运行yarn build,即可看到当前打包好的dist.js文件
使用webpack build支持IE,用babel-loader打包js
安装babel-loader npm
使用babel-loader打包jsx
测试
yarn build
为webpack配置eslint
eslint-config-react-app 包含Create React App使用的可共享 ESLint 配置。npm link
让webpack可以感知到eslint的配置,从而在编译的过程中提示报错信息
在没加eslint-webpack-plugin之前,尽管编辑器中eslint报错,但在运行yarn build时,它仍能编译成功。如下图所示
加完之后的情况,此时不仅eslint报错,webpack构建时也会在控制台报错,这样很好地使用了eslint
使用babel-loader打包TypeScript
参考babel官网
添加一个test.tsx,并在index.js中引入,以下结果编译成功
让eslint支持TypeScript
让eslint支持ts,添加相关配置
运行yarn build发现此时编译仍可成功
修改后的效果
使用babel-loader打包tsx
生成tsconfig.json文件
编写tsx-demo.tsx文件并在index.js中引入进行测试
CRLF是什么?一、LF和CRLF是什么?二、LF和CRLF区别
让js和ts支持@alias
引入代码进行测试
让webpack支持scss
使用sass-loader npm
scss自动导入全局文件,scss共享变量给js
可以让项目中使用的css变量由同一份js和scss共同维护一份变量
webpack支持less文件
使用less-loader npm
less共享给js,对比scss和less
若要选择,则选择scss
stylus文件
使用stylus npm
webpack config重构,生产页面单独提取css文件
使用mini-css-extract-plugin webpack文档
自动生成HTML页面
使用html-webpack-plugin npm
webpack优化:单独打包runtime
单独打包runtime的原因
webpack优化:使用splitChunks将node依赖单独打包
在编译时缓存React等类库文件
webpack优化:固定modules
运行yarn build后,可以看到引入了三个js文件
optimizationmoduleids
webpack多页面
webpack优化:common插件
如果共有文件,则打包成一个文件;如果两个入口同时引用了一个文件,看这个打包后页面引入js的顺序
无限多页面的实现思路
只需将这两个参数设置为动态生成的即可满足要求。测试后大功告成!!!
最后附上源代码链接
其他文章
一咻:Webpack入门到精通 五(常用配置)
一咻:Webpack 入门到精通四 (插件)
一咻:Webpack入门到精通 三(Loader原理)
一咻:Webpack入门到精通 二(核心原理)
一咻:Webpack入门到精通 一(AST、Babel、依赖)