gpt4 book ai didi

reactjs - Jest - 无法使用动态导入模板字符串找到模块

转载 作者:行者123 更新时间:2023-12-03 13:39:39 29 4
gpt4 key购买 nike

好吧,我有一个使用 Webpack 和 Jest 来测试 React 的设置,并且还使用 Webpack 的别名,使用“@”符号作为我的项目目录“src/app”,我也知道它必须映射到 jest .config 使用“moduleNameMapper”属性与该别名正确对齐。

问题是有一个<Icon />实习生使用 ES 动态导入动态导入 .svg 图标的组件。

这是 jest.config.js 映射的正则表达式

'^@/': '/src/app/$1'

但只有在测试时才会中断

除了测试之外一切正常

我的文件夹结构如下:

config/
webpack-config/

src/
app/
assets/
img/
some images
svg/
icons/
cart.svg
components/
base/
core/
shared/
...
client/
...
server/
...

这是我正在使用的 Webpack 别名:

module.exports = {
extensions: ['.js', '.mjs', '.json', '.jsx', '.css'],
modules: paths.resolveModules,
alias: {
'@': paths.srcApp, // that just point
}
};

这是我的 jest.config 文件:

const paths = require('./config/paths');

module.exports = {
verbose: true,
collectCoverageFrom: ['src/**/*.{js,jsx,mjs}'],
setupFiles: [
'<rootDir>/node_modules/regenerator-runtime/runtime',
'<rootDir>/config/polyfills.js',
],
// A list of paths to modules that run some code to configure or set up the testing framework before each test.
setupFilesAfterEnv: ['<rootDir>config/jest/setup.js'],
testMatch: [
'<rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}',
'<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}',
],
testEnvironment: 'node',
testURL: 'http://localhost',
modulePaths: ['src'],
moduleNameMapper: {
'^@[/](.+)': '<rootDir>/src/app/$1',
},
transform: {
'^.+\\.(js|jsx|mjs)$': '<rootDir>/node_modules/babel-jest',
'^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
'^(?!.*\\.(js|jsx|mjs|css|json|svg)$)': '<rootDir>/config/jest/fileTransform.js',
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$'],
moduleDirectories: paths.resolveModules,
moduleFileExtensions: ['js', 'json', 'jsx', 'node', 'mjs'],
};

这是我正在测试的组件

// @flow strict
import React, { useState } from 'react';

import './Icon.scss';

type PropsType = {
name: string,
selected?: string,
size: number | string
};

const Icon = ({ name, size }: PropsType) => {
const [iconPath, setIconPath] = useState('');
(async () => {
const icon = await import(`@/assets/svg/icons/${name}.svg`);
setIconPath(icon.default);
})();

return (
<img
alt={`icon ${name}`}
className="icon"
style={{
height: `${size}px`,
width: `${size}px`,
}}
src={iconPath}
/>
);
};

Icon.defaultProps = {
size: 16,
};

export default Icon;


这是测试

// @flow strict
import React from 'react';
import {
render,
} from 'react-testing-library';

import Icon from './Icon';

describe('Icon', () => {
it('should have "name" with the path of the icon', () => {
const { container } = render(<Icon name="cart" />);
});
});

这是输出

Configuration error:

Could not locate module @/assets/svg/icons/${name}.svg mapped as:
/Users/jero/Documents/my-shit/react-shop/src/app/assets/svg/icons/${name}.svg.

Please check your configuration for these entries:
{
"moduleNameMapper": {
"/^@[\/](.+)/": "/Users/jero/Documents/my-shit/react-shop/src/app/$1"
},
"resolver": null
}

有趣的是,当我将这个正则表达式用于 jest.config

moduleNameMapper: {
'/^@\/(.*)$/': '<rootDir>/src/app$1'
}

错误已经消失,但是当组件在测试时导入其他组件时,错误会中断:

 FAIL  src/app/components/shared/ImgLoader/ImgLoader.test.js
● Test suite failed to run

Cannot find module '@/components/base/Spinner/Spinner' from 'ImgLoader.js'

However, Jest was able to find:
'./ImgLoader.js'
'./ImgLoader.scss'
'./ImgLoader.test.js'

You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'node', 'mjs'].

See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

2 | import React, { useState } from 'react';
3 |
> 4 | import Spinner from '@/components/base/Spinner/Spinner';
| ^
5 |
6 | import './ImgLoader.scss';
7 |

at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:230:17)
at Object.<anonymous> (src/app/components/shared/ImgLoader/ImgLoader.js:4:1)

这是<ImageLoader />

// @flow strict
import React, { useState } from 'react';

import Spinner from '@/components/base/Spinner/Spinner';

import './ImgLoader.scss';

type PropsType = {
src: string
};

function ImgLoader({ src }: PropsType) {
const [imgObj, setImg] = useState({ img: null, isLoading: true });
const image = new Image();

image.onload = () => setImg({ img: image.src, isLoading: false });
image.src = src;

return (
imgObj.isLoading ? (<Spinner />) : (<img className="imgLoader img-fluid" src={imgObj.img} alt="img" />)
);
}

export default ImgLoader;

及其测试路线

// @flow strict

import React from 'react';
import {
render,
} from 'react-testing-library';
import ImgLoader from './ImgLoader';

describe('ImgLoader', () => {
it('tests \'src\'', () => {
const src = 'https://static.street-beat.ru/upload/resize_cache/iblock/d69/450_450_1/d699afc7b3428f2f51c2f2de6665b506.jpg';
const { container } = render(<ImgLoader src={src} />);
console.log('container', container);

});
});

我相信与动态导入有关?

最佳答案

这是我修复它的方法,问题是 Jest 由于某种原因,在动态导入中使用模板文字时会提示。因此,要修复它,只需使用普通的字符串连接即可。

(async () => {
// $FlowIgnore
const icon = await import('@/assets/svg/icons/' + name + '.svg');
setIconPath(icon.default);
})();

关于reactjs - Jest - 无法使用动态导入模板字符串找到模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56112953/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com