[英]import mathjax throws error @types/mathjax/index.d.ts is not a module
我正在尝试在 TypeScript 文件中导入 MathJax。
您可以通过以下步骤进行重现:
tsc --init
npm init -y
npm i mathjax @types/mathjax
echo "import { MathJax } from 'mathjax';" > index.ts
我已经尝试了以下所有重要语法:
import { MathJax } from 'mathjax';
import mathjax from "mathjax";
import * as mathjax from "mathjax"
import { * as MathJax } from "mathjax";
但都返回以下错误:
'../node_modules/@types/mathjax/index.d.ts' is not a module.
我也试过像这样将mathjax
添加到我的tsconfig.app.json
中的types
(但这也没有帮助)
"types": [
"mathjax"
]
这个答案是在 web 项目中使用 MathJax 编写的。 如果您不是这种情况,则其中大部分内容仍然适用,因为它与您明确使用的 Typescript 相关。
无论今天的情况如何,MathJax 历史上都是在浏览器中下载的,不应像其他 npm 包一样导入到针对 web 的项目中。 在Installation and use
at https://www.npmjs.com/package/mathjax下,您可以看到,如果您正在制作后端 Node 应用程序,则只能在这样的项目中使用 MathJax,否则应导入 MathJax在带有脚本的前端。 您可以将您自己的 MathJax 副本作为 static 文件资源托管在您的 web 服务器上,并从前端的script
标记中加载它(很像任何 CDN),但您不应该像使用常规一样将它构建到前端npm 将其导入到源文件中。 为什么这很重要? 因为它会影响 MathJax 在历史上和今天的组织方式,进而影响它在 Typescript 项目中的处理方式。
MathJax 有两个版本,MathJax 2 和 3。2 在内部和语法上与版本 3 有很大不同,但即使推荐使用版本 3,它仍在使用。 来自 npmjs.org 的mathjax
是 MathJax 3 package。如果您 go 到 MathJax Github repo ,您可以下载旧的包,但我认为它们不能作为 npm 包使用。 在Server integration
下的官方 MathJax 页面上,您可以阅读有关如何在后端下载 MathJax 的信息。 您还看到那里有两个 npm 包: mathjax
和mathjax-full
其中后者包含“完整源代码”。 MathJax 是用 Typescript 支持编写的,所以我们可以期望有类型。 如果您访问这些包的 npmjs.org 条目( https://www.npmjs.com/package/mathjax和https://www.npmjs.com/package/mathjax-full ),您会看到mathjax-full
包含mathjax
没有的类型。 这也可以通过期待node_modules
中下载的包来看出。
那么 package @types/mathjax
是什么? 嗯,经过检查,我们可以看到它连接到 MathJax 版本 2,因为它的类型声明涉及MathJax.Hub
的使用,它只在版本 2 中使用。还有它的index.d.ts
,当什么都没有时类型的入口点比
import mathjax from "mathjax"
或者
import * as mathjax from "mathjax"
声明一个名称空间,其中包含导出
declare namespace MathJax {
export ...
export ...
}
命名空间在 Javascript 中用于将代码组织到不同的不相交的组件中,这是一种早期的模块替代方案,它在没有命名空间的情况下做同样的事情。 在 Typescript 文档 ( https://www.typescriptlang.org/docs/handbook/modules.html ) 中,字面意思是In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module
. package @types/mathjax
没有那个,这导致它不是编译器报告的模块。
因此,除了@types/mathjax
由于版本不同而未连接到 npm package mathjax
(我知道这是一个糟糕的组织)之外,它也不支持现代模块语法。 我会说它也很旧但是它最近发布了所以坦率地说,我不知道它是关于什么的,也许它与 MathJax 通常的导入方式有关,或者它应该在其他一些非常特殊的地方工作情况。 我所知道的是,根据 Typescript 文档,这种类型 package 不被视为模块(如您的编译器所示)并且其类型与 MathJax 版本 3 不一致,例如,我绝对不认为有官方隶属关系在这个 package 和它应该支持的 package 之间。
所以给定mathjax-full
我们有类型,对吧? 是的,没错,但是mathjax-full
中的文件组织不适合您的用例。 首先,它缺少索引,因此没有合理的入口点可用于前面描述的那种import
语句(如前所述,当没有针对特定资源时,自然入口点是索引文件)。 包含的package.json
既不包含 package 信息也不包含类型信息(您可以在node_modules
中自行检查)。 即使当我尝试在没有 Typescript 的情况下使用它时,由于未定义require
的错误,它也无法工作。 总而言之,这个 package 并不意味着像您使用的平均 npm package 那样使用; 它应该用于那些希望使用 MathJax 源代码的人,绝对不应该用于“普通用户构建网络应用程序”用例。 对于那些, MathJax 应该用作一个单独的黑盒项目,通过脚本导入访问(同样,由于历史原因……这是 15 年前左右的事情)。
为了让它在你的用例中工作,我的意思是让你的编译器接受你的导入(没有别的),你可以做一些事情。 我这样说是因为我对 Typescript 在这里的工作方式也很感兴趣。
对于@types/mathjax
package,您可以将 go 放入其在index.d.ts
中的node_modules
中,并在底部(顶层)添加export default MathJax
。 现在该文件具有全局导出,因此,导入语句如
import * as mathjax from "mathjax"
import mathjax from "mathjax"
不会导致您之前看到的投诉。 由于我之前简要描述的require
错误,它仍然无法工作。
对于mathjax-full
,通过检查node_modules
中的代码,您可以看到js
子目录中的源代码中确实有 Typescript 个文件。 但由于没有索引(也明确提示 package 不应通过导入在 web 项目中使用),默认导入将不起作用(编译器会抱怨类型)。 但是,如果您以特定资产为目标,例如
import { mathjax } from "mathjax-full/js/mathjax"
它会找到相应的类型,你不会得到错误。 你实际上得到了某种 MathJax object 但我不知道它是否会一直工作(如果你想试试)。 此外,我怀疑你会在你的包中得到很多额外不需要的文件(或者不得不花很多时间来定制 tree-shaking),因为 MathJax 被用来确定它在使用时需要什么文件并且它可能很难打包器在构建时确定这一点。
最好的方法是对 MathJax 使用 React package。 在这里我会推荐我自己的 package better-react-mathjax
( https://www.npmjs.com/package/better-react-mathjax ) 但也有其他的。 这些包试图弥合 MathJax 和 React 之间的差距,就像您现在正在体验的那样。
如果您想以更复杂的方式进行操作,您可以使用 MathJax 包中的源代码并将它们作为 static 文件资源的一部分包含在内,然后在 React 中注入一个script
标签,该标签使用 MathJax 启动脚本从你的 static 后端。 如果您不想托管自己的副本,也可以这样做并从 CDN 获取相同的文件。
如果您真的需要在后端使用 MathJax,我会调查mathjax-full
package 并尝试将之前指向的官方 MathJax 文档中关于在 Node 中使用它的说明转换为您的用例,使用显式导入而不是默认导入获得类型支持的。
我代表您检测到对代码组织和模块的某种兴趣(可能是错误的),这是一个复杂的主题。 尝试编写自己的 package 并通过 npm 进行分发,以了解 npm、Node、Typescript、ecmascript 模块、commonjs 模块等所扮演的角色。 了解不同的模块格式以及如何允许它们在 Typescript 项目中使用esModuleInterop
和allowSyntheticDefaultImports
等功能进行交互也是重要的主题,通过分发您自己的 package,您将真正了解项目中源代码和源代码的差异包中的代码。
这有效: import * as MathJax from 'mathjax';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.