开玩笑无法解析模块别名
Posted
技术标签:
【中文标题】开玩笑无法解析模块别名【英文标题】:jest cannot resolve module aliases 【发布时间】:2020-02-13 00:56:07 【问题描述】:我正在使用一个名为 module-alias 的 npm 模块。我在 tsconfig.json 和 package.json 中映射了一些模块
tsconfig.json
"compilerOptions":
"baseUrl": "./src",
"paths":
"@config/*": ["config/*"],
"@interfaces/*": ["interfaces/*"],
"@services/*": ["services/*"]
,
"module": "commonjs",
"target": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"sourceMap": true,
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src",
"allowSyntheticDefaultImports": true /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
package.json
...
"_moduleAliases":
"@config": "src/config",
"@interface": "src/interface",
"@services": "src/services"
,
"jest":
"moduleNameMapper":
"@config/(.*)": "src/config/$1",
"@interface/(.*)": "src/interface/$1",
"@services/(.*)": "src/services/$1"
,
"moduleFileExtensions": ['js', 'json', 'jsx', 'ts', 'tsx', 'node']
,
...
server.ts
import logger from '@config/logger';
当我运行npm start
时一切正常,但是当我运行 jest 时它给了我一个错误
FAIL src/test/article.spec.ts
● Test suite failed to run
Cannot find module '@config/logger' from 'server.ts'
However, Jest was able to find:
'rest/server.ts'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].
有人知道问题出在哪里吗?谢谢
解决方案对我有用(2019 年 18 月 10 日更新):
使用以下代码创建一个 jest.config.js:
module.exports =
"roots": [
"<rootDir>/src/"
],
"transform":
"^.+\\.tsx?$": "ts-jest"
并更新 package.json 中的 moduleNameMapper:
...
"_moduleAliases":
"@config": "./src/config",
"@interfaces": "./src/interfaces",
"@services": "./src/services"
,
"jest":
"moduleNameMapper":
"@config/(.*)": "<rootDir>/src/config/$1",
"@interfaces/(.*)": "<rootDir>/src/interfaces/$1",
"@services/(.*)": "<rootDir>/src/services/$1"
...
【问题讨论】:
您应该从问题中删除您的解决方案并添加您自己的答案。 【参考方案1】:几个小时后,我设法完成了这项工作。我会尽力简化它以节省其他人的时间并使其顺利进行。
我的应用属于以下堆栈:
用于 API 构建 (.ts
) 的 Typescript(tsc
和 ts-node/register
,没有 Babel)
反应(.tsx
使用 Webpack)
jest
用于 API 测试(无 Babel)
testcafe
用于 UI/E2E
VSCode 作为 IDE
重点说明:
-
对我有用的解决方案是别名前必须有“@”字符。
module-alias
理论上不需要它,但是当我们应用模块名称映射器时,Jest 会迷路。
“webpack”别名和“tsconfig”之间的命名需要保持一致。 VSCode 有必要不要在 TSX 文件中用红色下划线模块名称。
无论您的文档结构如何,这都应该有效,但如果遇到问题,请记住调整 baseUrl
和开玩笑配置。
在 VSCode 中为 .tsx
文件应用更改时,不要担心某些路径带有下划线。这是暂时的,因为 VSCode 似乎只有在所有文件正确连接时才能掌握它。一开始它让我失去了动力。
首先,从https://www.npmjs.com/package/module-alias 安装module-alias
与
npm i --save module-alias
然后添加到您的初始启动文件(仅适用于 .ts
文件,即您的应用程序服务器):
require('module-alias/register')
正如module-alias
文档所示。然后设置tsconfig.ts
。请记住,baseUrl
在这里也很重要:
"compilerOptions":
"baseUrl": ".",
...
"paths":
"@helpers/*": ["src/helpers/*"],
"@root/*": ["src/*"]
...
然后设置你的webpack.js
:
const path = require('path')
...
resolve:
...
alias:
'@helpers': path.resolve(__dirname, 'src', 'helpers'),
'@root': path.resolve(__dirname, 'src')
然后设置你的package.json
:
...
"_moduleAliases":
"@helpers": "src/helpers",
"@root": "src"
然后设置您的 jest
配置(我仅附上应用更改时相关的内容):
rootDir: ".",
roots: ["./src"],
transform:
"^.+\\.ts?$": "ts-jest"
,
moduleNameMapper:
"@helpers/(.*)": "<rootDir>/src/helpers/$1",
"@root/(.*)": "<rootDir>/src/$1"
,
...
现在,我们需要处理构建过程,因为tsc
无法将别名转换为它们的相关兄弟。
为此,我们将使用 tscpaths
包:https://github.com/joonhocho/tscpaths。这个很简单。
所以考虑到您的构建命令只是:
tsc
现在变成了
tsc && tscpaths -p tsconfig.json -s ./src -o ./dist/server
您需要调整 -s
和 -o
以适应您的结构,但是当您在构建后检查 .js
文件时,您应该查看相对路径是否正确链接(并相应地进行调试)。
就是这样。它应该像王牌一样工作。这很多,但值得。
控制器 (.ts) 和 React 组件 (.tsx) 文件中的调用示例:
import IApiResponse from '@intf/IApi'
【讨论】:
"moduleNameMapper" 是为我做的,谢谢你的回复!【参考方案2】:我认为您没有在 tsconfig
中正确配置路由,因为路径缺少 src
文件夹(虽然它们出现在您的 package.json 模块别名配置中):
您的tsconfig
代码:
"@config/*": ["config/*"],
"@interfaces/*": ["interfaces/*"],
"@services/*": ["services/*"]
我认为应该是这样的:
"@config/*": ["src/config/*"],
"@interfaces/*": ["src/interfaces/*"],
"@services/*": ["src/services/*"]
【讨论】:
似乎 compilerOptions 中的 baseUrl 可以通知编译器在哪里找到模块,因为在我将 'src' 添加到路径后它给了我打字错误 我什至无法启动我的应用程序,它也让我找不到模块'@config/...' 哇,这真的让我很困惑。我有一个带有 ts 和 jest 的工作配置,我正在指定指向我的路径的完整路径,指示src
段。我在你的 package.json 中看到你指的是 'interface' ,但是在你的 tsconfig 中有一个对 'interfaces' 的引用(带有额外的s
)。也许是相关的,我不确定。
我创建了一个 jest.config.js 并添加了两个选项,包括“roots”和“transform”,然后一切正常。以上是关于开玩笑无法解析模块别名的主要内容,如果未能解决你的问题,请参考以下文章
React Webpack 错误“找不到模块:错误:无法解析 'public/bundle.js' in..”/“字段 'browser' 不包含有效的别名配置”
Gatsby - webpack 无法使用 `gatsby-plugin-alias-imports` 解析别名导入