库
例子
我们从一个简单的例子去看,比如在规则中的exports-last
, 他的作用是确保export
放到最后导出
exports-last
/** valid */
const foo = 'bar'
export default foo
export const bar = true
/** invalid */
export default 'such foo many bar'
export const so = 'many'
const foo = 'bar'
export const exports = ':)'
export const i = 'cant'
export const even = 'count'
export const how = 'many'
function isNonExportStatement({ type }) {
return type !== 'ExportDefaultDeclaration'
&& type !== 'ExportNamedDeclaration'
&& type !== 'ExportAllDeclaration';
}
module.exports = {
meta: {
type: 'suggestion',
docs: {
category: 'Style guide',
description: 'Ensure all exports appear after other statements.',
url: docsUrl('exports-last'),
},
schema: [],
},
create(context) {
return {
Program({ body }) {
/**使用findLastIndex函数查找body中最后一个非导出语句的索引 */
const lastNonExportStatementIndex = findLastIndex(body, isNonExportStatement);
if (lastNonExportStatementIndex !== -1) {
/** 获取索引位置之前的所有节点(包括非导出语句)*/
body.slice(0, lastNonExportStatementIndex).forEach((node) => {
// 如果节点不是非导出语句,说明它是一个导出语句
if (!isNonExportStatement(node)) {
context.report({
node,
message: 'Export statements should appear at the end of the file',
});
}
});
}
},
};
},
};
eslint插件中的meta属性
meta
对象提供了一些元数据,用于描述规则的基本信息和行为。这些信息帮助ESLint
和用户了解规则的目的、使用方式以及如何与ESLint的其他部分交互
meta: {
// "problem"、"suggestion"、"layout" 或 "directive"
type: "suggestion",
docs: {
description: "描述",
category: "Best Practices",
recommended: false,
},
// 一个JSON Schema对象,用于定义规则可以接受的选项
schema: [
{
type: "object",
properties: {
ignoreStrings: {
type: "boolean",
},
ignoreTemplateLiterals: {
type: "boolean",
},
},
additionalProperties: false,
},
],
// 报错信息提示,通常用context.report({messageId: 'unexpectedConcatenation'})
messages: {
unexpectedConcatenation: "Unexpected concatenation of literals.",
},
// 指示规则是否能够自动修复发现的问题。如果设置为true,则在ESLint的命令行界面中可以使用--fix选项自动修复问题
fixable: "code",
// 指示规则是否能够提供代码修复的建议。这通常用于--fix选项无法自动修复问题,但规则可以提供一些手动修复建议的情况
hasSuggestions: true,
}
create 方法
在create 方法中我们可以解析遍历AST
, 其入参是context
,有以下属性
- parserOptions-编译器选项,就是我们.eslintrc.js里的那个
- id-规则id
- options-通过这个可以拿到规则传进来的参数
- getFilename()-返回源文件文件名
- getScope()- 返回当前遍历节点的作用域
- getSourceCode()- 返回SourceCode对象,就是源码对象,很有用
- report()- 当校验不通过的时候,通过这个方法输出错误信息
- 可以通过
context.settings
拿到.eslintrc.js
全局设置的settings
在来另一个例子,使用fix
去修复代码
module.exports = {
meta: {
type: 'suggestion',
docs: {
category: 'Static analysis',
description: 'Forbid import of modules using absolute paths.',
url: docsUrl('no-absolute-path'),
},
fixable: 'code',
schema: [makeOptionsSchema()],
},
create(context) {
function reportIfAbsolute(source) {
if (isAbsolute(source.value)) {
context.report({
node: source,
message: 'Do not import modules using an absolute path',
fix(fixer) {
const resolvedContext = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
// node.js and web imports work with posix style paths ("/")
let relativePath = path.posix.relative(path.dirname(resolvedContext), source.value);
if (!relativePath.startsWith('.')) {
relativePath = `./${relativePath}`;
}
return fixer.replaceText(source, JSON.stringify(relativePath));
},
});
}
}
const options = { esmodule: true, commonjs: true, ...context.options[0] };
return moduleVisitor(reportIfAbsolute, options);
},
};
自己写一个plugin
- 导入的模块名需要是下划线或是驼峰式
- 除了个别目录外不能跨目录导入文件,比如说不能跨模块导入组件等,但可以在子级下导入文件