有一个第三方的全JavaScript npm scoped软件包,我们将其称为@foo,其中包含一个名为bar的模块。我想在我的打字稿.tsx文件中使用react组件@ foo / bar / X。尝试import X from '@foo/bar/X'
时,我立即遇到“找不到模块”的问题。如何使用@types打字稿来解决此问题,以解决模块X并使Webpack正常运行?
答案 0 :(得分:0)
我的起点是关于如何使用打字稿https://www.typescriptlang.org/docs/handbook/react-&-webpack.html使用react和webpack的介绍。但是,上述说明不能解决我要使用的react组件没有@types的问题。所以我的第一步是我需要添加@types。
作用域模块@ foo / bar有一个重要的细微差别,那就是它将其所有子组件分解为单个子模块,例如@ foo / bar / X,@ foo / bar / Y和@ foo / bar /具有@ foo / bar的Z本身没有任何功能。我们将看到,这是一个重要的细微差别,这比我不必在我的打字稿中导入作用域模块要复杂得多。
有nice blog post here关于如何将普通javascript导入打字稿的。不幸的是,所提议的方法存在缺点。即,在src / @ typings中添加“ index.d.ts”的想法有两个问题:
无论尝试哪种方法,我都知道我需要在我的打字稿文件中包含此导入语句:
import X from '@foo/bar/X';
ReactDOM.render(
<X/>,
document.getElementById("example")
);
在某个地方,我需要在“ .d.ts”声明文件(如index.d.ts)中包含以下内容,这很明显:
declare module '@foo/bar';
declare module '@foo/bar/X';
但是运行“ webpack”会产生Module not found: Error: Can't resolve '@foo/bar/X'
我决定使用此标志运行打字稿编译器(tsc),以查看tsc尝试解析模块的可能位置。
tsc --traceresolution
使用traceresolution标志,我可以看到一些非常有趣的东西:在tSC搜索的node_modules / @ types下的位置是非常不可预料的(因此是webpack的搜索位置,因为webpack遵循与tsc相同的规则)。期望在node_modules/@types/foo__bar
下找到我的index.d.ts文件。没错,对于范围包,您不能有node_modules/@types/@foo/bar/index.d.ts
。相反,您必须在名为foo__bar
的@types下使用具有DOUBLE UNDERSCORE的单个文件夹。
基于此知识,我创建了@ types / foo__bar。我将package.json从@ foo / bar模块复制到@ types / foo__bar。我清除了@types不需要的所有脚本和其他无用的东西,并将其剥离为:
{
"name": "@types/@sfoo/bar",
"version": "2.6.0",
"peerDependencies": {
"react": "^16.3",
"react-dom": "^16",
"styled-components": "^3"
},
"dependencies": {
...
},
"engines": {
"node": ">=6"
},
"gitHead": "ac0288aaa47a4f15e56db3a5eff4424fb7905419",
"main": "",
"types": "index"
}
但是还有另一个问题!即使在tsc可以解析我的@types之后,webpack仍然产生module not found: can't resolve @foo/bar
。那么,为什么Webpack找不到它呢?再次,我发现了一个可以向我展示更多内容的标志:
webpack --verbose
但是在这里我运气不佳,因为webpack规则就像模块解析的打字稿规则一样。但是从--verbose输出中,我确实注意到webpack感兴趣的一个文件是node_modules/@foo/bar/index.js。但是,bar模块缺少任何index.js,因为它实际上只是一个围绕@ foo / bar / X等子模块的空封闭模块。我不知道这是Webpack的错误还是Webpack的功能,但是将一个空的index.js添加到了node_modules / @ foo / bar pacified webpack中,而我的简单示例现在可以与加载时浏览器中显示的组件X一起使用HTML页面。