通过“no-var-requires”ESLint 规则,导入没有声明文件的模块
Posted
技术标签:
【中文标题】通过“no-var-requires”ESLint 规则,导入没有声明文件的模块【英文标题】:pass "no-var-requires" ESLint rule with an import of a module without declaration file 【发布时间】:2022-01-13 14:22:08 【问题描述】:在我的NodeJS/TypeScript
项目中,我使用的是fluent-ffmpeg
,它运行良好。
为了使用它,我需要导入ffmpeg-installer/ffmpeg
和ffprobe-installer/ffprobe
的path
属性。
ffmpeg
导入看起来像:
import * as ffmpegInstaller from "@ffmpeg-installer/ffmpeg";
@ffmpeg-installer/ffmpeg
模块的types
文件夹下存在声明文件index.d.ts
使之成为可能。
关于ffprobe
这是不可能的,因为缺少像上面提到的那样的声明文件。尝试时:import * as ffprobeInstaller from "@ffprobe-installer/ffprobe";
出现错误:
找不到模块“@ffprobe-installer/ffprobe”的声明文件。 '<...>/node_modules/@ffprobe-installer/ffprobe/index.js' 隐含地具有 'any' 类型。 尝试
npm i --save-dev @types/ffprobe-installer__ffprobe
(如果存在)或添加包含declare module '@ffprobe-installer/ffprobe';
ts(7016) 的新声明(.d.ts)文件
npm i --save-dev @types/ffprobe-installer__ffprobe
都没有给出任何东西。
所以我改用const ffprobeInstaller = require("@ffprobe-installer/ffprobe");
,它可以工作。
然而,ESLint
来了并抱怨:
Require 语句不是 import 语句的一部分。 eslint (@typescript-eslint/no-var-requires)
所以我尝试将其替换为:import ffprobeInstaller = require("@ffprobe-installer/ffprobe");
,正如ESLint
文档中所建议的那样,但后来我又得到了Could not find a declaration file...ts(7016)
。
我可以采取一些方向来解决这个问题:
创建我自己的声明文件 禁用no-var-requires
规则或在本地忽略它
我的问题是:如何在不创建声明文件或禁用规则的情况下通过 ESLint
的 no-var-requires
规则。
【问题讨论】:
你试过写// eslint-disable-next-line @typescript-eslint/no-var-requires
,就在require
的上方吗?
【参考方案1】:
从两个方面考虑你的问题,
-
如何传递 typescript -> 当然你需要一个声明文件,要么写你自己的文件,要么安装一个已有的包
如何传递 eslint -> 使用 import 语句而不是 var-requires。
有趣的是require
有any
返回类型。这就是为什么你认为你已经解决了打字稿部分。但实际上,这个内置类型就像一个快速声明文件,会失去类型限制。
interface NodeRequireFunction
(id: string): any;
总而言之,无论是文件还是隐式地创建声明都是必需的。而 eslint 只是偶然引入的东西。
【讨论】:
【参考方案2】:@ffprobe-installer/ffprobe 是一个纯 javascript 包,没有可用的类型。如果您只想使用它并将其中的所有内容视为任何内容,那么您可以按照编译器的建议进行操作并创建一个新的声明文件。它只需要包含该行
declare module '@ffprobe-installer/ffprobe'
例如在源代码的根目录下创建一个名为 ffprobe.d.ts 的文件,添加上面的行,编译错误就会消失。
如果您想通过使用 require 而不是 import 来绕过编译器错误,那么您必须使用 eslint-disable-next-line 或类似方法禁用 lint 规则。没有办法阻止 eslint 抱怨使用 require 而不在某处禁用规则,因为规则正在做它应该做的事情。
【讨论】:
以上是关于通过“no-var-requires”ESLint 规则,导入没有声明文件的模块的主要内容,如果未能解决你的问题,请参考以下文章