跳至主要內容
版本:29.7

與 webpack 搭配使用

Jest 可用於使用 webpack 管理資源、樣式和編譯的專案。webpack 確實 提供了一些比其他工具更獨特的挑戰,因為它直接與您的應用程式整合,以允許管理樣式表、圖像和字型等資源,以及廣泛的編譯至 JavaScript 語言和工具生態系統。

webpack 範例

讓我們從常見的 webpack 設定檔開始,並將其轉換為 Jest 設定。

webpack.config.js
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',
],
},
};

如果您有 Babel 轉換的 JavaScript 檔案,您可以透過安裝 babel-jest 外掛程式來 啟用對 Babel 的支援。非 Babel JavaScript 轉換可以使用 Jest 的 transform 設定選項來處理。

處理靜態資源

接下來,讓我們設定 Jest 以優雅地處理資源檔案,例如樣式表和圖像。通常,這些檔案在測試中並非特別有用,因此我們可以安全地模擬它們。但是,如果您使用 CSS 模組,最好模擬 className 查詢的代理程式。

jest.config.js
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',
},
};

以及模擬檔案本身

__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports = 'test-file-stub';

模擬 CSS 模組

您可以使用 ES6 Proxy 來模擬 CSS 模組

npm install --save-dev identity-obj-proxy

然後您在 styles 物件上的所有 className 查詢都會原樣傳回 (例如,styles.foobar === 'foobar')。這對於 React 快照測試 非常方便。

jest.config.js (適用於 CSS 模組)
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') 可以寫成

fileTransformer.js
const path = require('path');

module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
jest.config.js (適用於自訂轉換器和 CSS 模組)
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 的 modulesextensions 選項,Jest 的 moduleDirectoriesmoduleFileExtensions 選項有直接的類比。

jest.config.js
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

jest.config.js
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 選項。

jest.config.js
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 install --save-dev @babel/preset-env

然後,你會想要按照下列方式設定 Babel

.babelrc
{
"presets": ["@babel/preset-env"]
}
提示

Jest 會快取檔案以加快測試執行速度。如果你更新了 .babelrc,而 Jest 沒有按預期運作,請嘗試執行 jest --clearCache 來清除快取。

提示

如果你使用動態匯入(import('some-file.js').then(module => ...)),你需要啟用 dynamic-import-node 外掛程式。

.babelrc
{
"presets": [["env", {"modules": false}]],

"plugins": ["syntax-dynamic-import"],

"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}

有關如何將 Jest 與 webpack 搭配 React 使用的範例,你可以在此查看。