Using with webpack
Jest 可以用于使用 webpack 来管理资源、 样式和编译的项目中。 webpack 确实 相比超过其他类似工具来说,展示出一些特有的优势,因为它直接与你的app整合,允许管理资源文件,如图像和字体,并带有可以将系统编译为JavaScript 语言和工具。
Webpack 示例 #
我们通过以下常见的webpack 配置文件,将其转化为符合Jest使用的配置。
// webpack.config.js module.exports = { module: { loaders: [ {exclude: ['node_modules'], loader: 'babel', test: /\.jsx?$/}, {loader: 'style-loader!css-loader', test: /\.css$/}, {loader: 'url-loader', test: /\.gif$/}, {loader: 'file-loader', test: /\.(ttf|eot|svg)$/}, ], }, resolve: { alias: { config$: './configs/app-config.js', react: './vendor/react-master', }, extensions: ['', 'js', 'jsx'], modules: [ 'node_modules', 'bower_components', 'shared', '/shared/vendor/modules', ], }, };
如果你有需要Babel转化的 Js文件,你可以通过安装babel-jest
插件来 启用Babel 。 无需Babel转换的js文件,可以通过Jest的transform
参数设定来处理。
处理静态文件 #
接下来,让我们配置Jest,使其优雅地处理资源文件,如样式表和图像。 通常,这些文件在测试中无足轻重,因为我们可以安全地mock他们。 然而, 如果你使用CSS模块,那么最好是给你的类名查找模拟一个代理。
// package.json { "jest": { "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" } } }
所有mock文件本身:
// __mocks__/styleMock.js module.exports = {};
// __mocks__/fileMock.js module.exports = 'test-file-stub';
模拟 CSS 模块 #
npm install --save-dev identity-obj-proxy
然后在样式对象上,你的所有className查找都会原样返回 (如 styles.foobar === 'foobar'
) 这对React的Snapshot Testing是相当方便的.
// package.json (for CSS Modules) { "jest": { "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" } } }
请注意在Node 6是默认启用Proxy。如果你不是Node 6,请确保你通过调用
node --harmony_proxies node_modules/.bin/jest
来使用Jest。
如果 moduleNameMapper
不能满足您的要求,你可以使用Jest 的transform
配置参数来设定如何转换。 例如,编译器会返回文件的基本文件名 (例如require('logo.jpg');
returns 'logo'
) 可以写成:
// fileTransformer.js const path = require('path'); module.exports = { process(src, filename, config, options) { return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; }, };
// package.json (for custom transformers and CSS Modules) { "jest": { "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可以处理的文件类型。
注:如果你bael-jest和额外的代码预处理器,你必须明确的定义babel-jest为你的Js代码的转换器,并且你需要映射所有.js
文件到babel-jest模块。
"transform": { "^.+\\.js$": "babel-jest", "^.+\\.css$": "custom-transformer", ... }
配置Jest来搜寻文件 #
现在Jest知道如何处理我们的文件了, 接下来我们需要告诉它如何找到它们。 webpack的modulesDirectories
, 和 extensions
选项都是和Jest的moduleDirectories
和 moduleFileExtensions
选项类似的.
// package.json { "jest": { "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
选项。
同样 webpack的 resolve.root
选项,如设置的 NODE_PATH
env变量,都可以设置或使用 modulePaths
选项。
// package.json { "jest": { "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
选项。
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "^react(.*)$": "<rootDir>/vendor/react-master$1", "^config$": "<rootDir>/configs/app-config.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
配置完成。 webpack 是一个复杂和灵活的工具,所以你可能需要做一些调整,以符合你的特定应用的需要。 幸运的是对于大多数项目来说,使用Jest来处理webpack配置,应该会更灵活。
注︰ 对于更复杂的 webpack 配置,你可能需要研究一些项目,例如︰ babel-plugin-webpack-loaders。
使用 webpack 2 #
webpack 2 提供原生支持ES模块。 但是,Jest是通过Node运行,因此需要ES模块转换成CommonJS模块。 所以,如果你使用webpack2, 你很有可能需要配置Babel仅在test
环境中转换ES模块到CommonJS模块。
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "env": { "test": { "plugins": ["transform-es2015-modules-commonjs"] } } } Context | Request Context
注意:Jest会通过缓存文件来加速测试的执行。如果你更新了 .babelrc 文件,但是Jest还是不工作,尝试加入
--no-cache
参数来运行Jest。
如果你使用动态导入(import('some-file.js').then(module => ...)
), 你需要启用dynamic-import-node
插件。
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "plugins": ["syntax-dynamic-import"], "env": { "test": { "plugins": ["dynamic-import-node"] } } }