使用ESLint Node.js API lint文本遇非标准扩展名错误的解决咨询
问题
我按照ESLint官方文档尝试通过编程方式运行ESLint,代码如下:
import { ESLint, Linter } from "eslint"; import path from "path"; import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const ESLINT: Linter.Config = { env: { browser: true, es2021: true, }, extends: ["prettier"], parser: "@typescript-eslint/parser", parserOptions: { ecmaVersion: "latest" as const, project: [`${__dirname}/tsconfig.lib.json`], sourceType: "module" as const, }, plugins: [ "@typescript-eslint", "import", "simple-import-sort", "typescript-sort-keys", "sort-keys", "prettier", ], rules: { "@typescript-eslint/array-type": [ 2, { default: "generic", }, ], "@typescript-eslint/await-thenable": "error", "@typescript-eslint/consistent-type-definitions": [2, "type"], "@typescript-eslint/consistent-type-exports": "error", "@typescript-eslint/lines-between-class-members": "error", "@typescript-eslint/method-signature-style": "error", "@typescript-eslint/naming-convention": 0, "@typescript-eslint/no-array-constructor": "error", "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-for-in-array": "error", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "error", "@typescript-eslint/no-require-imports": "error", "@typescript-eslint/no-this-alias": "error", "@typescript-eslint/no-throw-literal": "error", "@typescript-eslint/no-unnecessary-condition": 0, "@typescript-eslint/no-unsafe-argument": "error", "@typescript-eslint/no-unsafe-assignment": "error", "@typescript-eslint/no-unsafe-member-access": "error", "@typescript-eslint/no-unsafe-return": "error", "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-useless-empty-export": "error", "@typescript-eslint/object-curly-spacing": [2, "always"], "@typescript-eslint/padding-line-between-statements": [ "error", { blankLine: "always", next: ["type"], prev: "*", }, ], "@typescript-eslint/prefer-function-type": "error", "@typescript-eslint/quotes": [ "error", "single", { allowTemplateLiterals: true, avoidEscape: true, }, ], "@typescript-eslint/space-before-blocks": ["error", "always"], "@typescript-eslint/type-annotation-spacing": ["error", { after: true }], curly: 2, "default-case": "error", "default-case-last": "error", "import/first": "error", "import/newline-after-import": "error", "import/no-duplicates": "error", "lines-between-class-members": "off", "no-array-constructor": "off", "no-throw-literal": "off", "object-curly-spacing": "off", "padding-line-between-statements": "off", "prettier/prettier": 2, "sort-keys": 0, "sort-keys/sort-keys-fix": 2, "space-before-blocks": "off", "typescript-sort-keys/interface": "error", "typescript-sort-keys/string-enum": "error", }, }; const text = `export namespace Back { export namespace Form { export type Post = { authorId: string content: string createdAt: string id: string title: string } export type User = { email?: string | null | undefined id: string name: string } } export type Base = { post: Form.Post user: Form.User } export type Name = keyof Base }`; const eslint = new ESLint({ overrideConfig: ESLINT, useEslintrc: false, }); const results = await eslint.lintText(text); const formatter = await eslint.loadFormatter("stylish"); const resultText = await formatter.format(results); console.log(resultText)
运行时报错:
$ npx ts-node-esm -P tsconfig.json test/make.ts <text> 0:0 error 解析错误:ESLint已配置为使用`parserOptions.project`: ./tsconfig.lib.json在`<tsconfigRootDir>/<text>`上运行 该文件的扩展名(``)是非标准的。你应该在配置中添加`parserOptions.extraFileExtensions` ✖ 1个问题(1个错误,0个警告)
我尝试在parserOptions中添加extraFileExtensions: [""],还是报错:
$ npx ts-node-esm -P tsconfig.json test/make.ts <text> 0:0 error 解析错误:ESLint已配置为使用`parserOptions.project`: ./tsconfig.lib.json在`<tsconfigRootDir>/<text>`上运行 发现`parserOptions.extraFileExtensions`选项中指定了意外的扩展名``。你是不是想写`.`? 但是该TSConfig不包含此文件。你可以: - 修改ESLint的包含文件列表,使其不包含此文件 - 修改该TSConfig以包含此文件 - 创建一个包含此文件的新TSConfig,并将其加入你的parserOptions.project ✖ 1个问题(1个错误,0个警告)
我的tsconfig.lib.json配置:
{ "compilerOptions": { "module": "ESNext", "target": "ESNext", "lib": ["es2020"], "sourceMap": true, "moduleResolution": "node", "strictNullChecks": true, "strict": true, "esModuleInterop": true, "noUncheckedIndexedAccess": true, "noErrorTruncation": true, "noImplicitAny": true, "declaration": true }, "include": [""] }
怎么在保留所有插件的前提下解决这个问题?
解决方案
方法1:给lintText指定TS文件名
用lintText时,默认把文本当作无扩展名的<text>文件,TypeScript ESLint解析器无法识别类型。只需在调用lintText时指定一个带.ts扩展名的虚拟文件名,就能让解析器正确识别:
修改这行代码:
const results = await eslint.lintText(text, { filePath: "dummy.ts" });
这个方法最简单,不需要改ESLint和TSConfig的其他配置,所有插件和规则都能正常使用。
方法2:调整TSConfig和ESLint配置
- 先修改
tsconfig.lib.json的include字段,让它包含所有文件(包括虚拟的文本文件):
{ "compilerOptions": { // 保持原有配置不变 }, "include": ["*"] }
- 然后在ESLint的
parserOptions里明确指定TS扩展名:
parserOptions: { ecmaVersion: "latest" as const, project: [`${__dirname}/tsconfig.lib.json`], sourceType: "module" as const, extraFileExtensions: [".ts"] },
这样解析器会把文本当作TS文件处理,同时TSConfig也能覆盖到这个虚拟文件,解决报错。
方法3:关闭项目类型检查(不推荐)
如果不需要TypeScript类型相关的规则,可以注释掉parserOptions.project配置,但这样会丢失@typescript-eslint很多类型检查能力,不过能保留所有插件:
parserOptions: { ecmaVersion: "latest" as const, // project: [`${__dirname}/tsconfig.lib.json`], sourceType: "module" as const, },
推荐用方法1,既简单又不会影响任何规则和插件的功能。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

