与 webpack 配合使用
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Jest 可用于使用 webpack 管理资源、样式和编译的项目。webpack 相比其他工具确实存在独特挑战,因为它直接集成到您的应用程序中,能够管理样式表、图片字体等资源,以及庞大的编译到 JavaScript 的语言和工具生态。
webpack 配置示例
让我们从一个常见的 webpack 配置文件开始,将其转换为 Jest 配置。
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
exclude: ['node_modules'],
use: ['babel-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.gif$/,
type: 'asset/inline',
},
{
test: /\.(ttf|eot|svg)$/,
type: 'asset/resource',
},
],
},
resolve: {
alias: {
config$: './configs/app-config.js',
react: './vendor/react-master',
},
extensions: ['.js', '.jsx'],
modules: [
'node_modules',
'bower_components',
'shared',
'/shared/vendor/modules',
],
},
};
如果您的 JavaScript 文件通过 Babel 转换,可以通过安装 babel-jest 插件来启用 Babel 支持。非 Babel 的 JavaScript 转换可以使用 Jest 的 transform 配置选项处理。
处理静态资源
接下来配置 Jest 优雅处理样式表和图片等资源文件。通常这些文件在测试中并不重要,我们可以安全地模拟它们。但如果使用 CSS Modules,则最好为 className 查询创建代理模拟。
module.exports = {
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
},
};
模拟文件内容如下:
module.exports = {};
module.exports = 'test-file-stub';
模拟 CSS Modules
您可以使用 ES6 Proxy 来模拟 CSS Modules:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev identity-obj-proxy
yarn add --dev identity-obj-proxy
pnpm add --save-dev identity-obj-proxy
bun add --dev identity-obj-proxy
这样所有在 styles 对象上的 className 查询都会原样返回(例如 styles.foobar === 'foobar')。这在 React 快照测试中非常实用。
module.exports = {
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': 'identity-obj-proxy',
},
};
如果 moduleNameMapper 无法满足需求,可以使用 Jest 的 transform 配置选项指定资源转换方式。例如,返回文件名基础的转换器(使 require('logo.jpg'); 返回 'logo')可这样编写:
const path = require('path');
module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
module.exports = {
moduleNameMapper: {
'\\.(css|less)$': 'identity-obj-proxy',
},
transform: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/fileTransformer.js',
},
};
我们已指示 Jest 忽略匹配样式表或图片扩展名的文件,转而引入模拟文件。您可以调整正则表达式来匹配 webpack 配置处理的文件类型。
如需同时使用其他代码预处理器,请务必显式包含默认的 babel-jest 转换器:
"transform": {
"\\.[jt]sx?$": "babel-jest",
"\\.css$": "some-css-transformer",
}
配置 Jest 定位文件
现在 Jest 知道如何处理文件,接下来需要告诉它如何_查找_文件。webpack 的 modules 和 extensions 选项在 Jest 中有对应的 moduleDirectories 和 moduleFileExtensions 选项。
module.exports = {
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
},
};
<rootDir> 是 Jest 使用的特殊标记,会被替换为项目根目录。多数情况下这是包含 package.json 的文件夹,除非您在配置中指定了自定义的 rootDir 选项。
类似地,Jest 中对应 webpack resolve.roots(替代 设置 NODE_PATH)的选项是 modulePaths。
module.exports = {
modulePaths: ['/shared/vendor/modules'],
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
},
};
最后,我们需要处理 webpack 的 alias。为此可以再次利用 moduleNameMapper 选项。
module.exports = {
modulePaths: ['/shared/vendor/modules'],
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
'^react(.*)$': '<rootDir>/vendor/react-master$1',
'^config$': '<rootDir>/configs/app-config.js',
},
};
完成!webpack 是复杂灵活的工具,您可能需要调整配置以满足特定应用需求。幸运的是对多数项目而言,Jest 完全能灵活处理您的 webpack 配置。
对于更复杂的 webpack 配置,您也可以研究以下项目:babel-plugin-webpack-loaders。
与 webpack 配合使用
除了按照前文描述安装 babel-jest 外,您还需要添加 @babel/preset-env:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/preset-env
yarn add --dev @babel/preset-env
pnpm add --save-dev @babel/preset-env
bun add --dev @babel/preset-env
然后按如下方式配置 Babel:
{
"presets": ["@babel/preset-env"]
}
Jest 会缓存文件以加速测试执行。如果您更新了 .babelrc 后 Jest 未按预期工作,可尝试运行 jest --clearCache 清除缓存。
如果使用动态导入 (import('some-file.js').then(module => ...)),需要启用 dynamic-import-node 插件。
{
"presets": [["env", {"modules": false}]],
"plugins": ["syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}
有关在 React 项目中使用 Jest 和 webpack 的示例,请参见此处。