在 Jest 测试中使用 webpack 的 worker-loader 解析导入

Posted

技术标签:

【中文标题】在 Jest 测试中使用 webpack 的 worker-loader 解析导入【英文标题】:Resolving imports using webpack's worker-loader in Jest tests 【发布时间】:2017-07-22 21:27:16 【问题描述】:

我正在编写 Jest 测试,但无法解决使用 webpack 的 worker-loader 的导入

import ImageInfoWorker from 'worker-loader?name=image_info!@WORKERS/image-info';

我还有一些其他别名在我的测试中可以正确解析,例如:

import Store from '@SUPPORT/store';
import * as api from '@SUPPORT/api';

这是来自package.json的相关sn-p

  "jest": 
    "moduleFileExtensions": ["js", "jsx"],
    "moduleNameMapper": 
      "^@CSS/(.*)$": "<rootDir>/css/$1",
      "^@COMPONENTS/(.*)$": "<rootDir>/js/components/$1",
      "^@MODELS/(.*)$": "<rootDir>/js/models/$1",
      "^@STORES/(.*)$": "<rootDir>/js/stores/$1",
      "^@SUPPORT/(.*)$": "<rootDir>/js/support/$1",
      "^(.*?)@WORKERS/(.*)$": "$1<rootDir>/js/workers/$2"
  

这是我的 webpack 配置的 resolve 部分:

        resolve: 
          extensions: ['.js', '.jsx'],
          modules: [process.env.NODE_PATH, 'node_modules'],
          alias: 
            '@CSS':        path.join(projectRoot, 'css'),
            '@COMPONENTS': path.join(projectRoot, 'js', 'components'),
            '@MODELS':     path.join(projectRoot, 'js', 'models'),
            '@STORES':     path.join(projectRoot, 'js', 'stores'),
            '@SUPPORT':    path.join(projectRoot, 'js', 'support'),
            '@WORKERS':    path.join(projectRoot, 'js', 'workers')
        
      ,

【问题讨论】:

您找到解决问题的方法了吗? @JuHwon 不,我们没有。 信息不足。你确定你在测试中运行 webpack 吗?问题是 worker-loader 是 webpack 的东西,所以你真的需要在测试之前构建。 jest 在 node 中运行,并且 node 没有 worker,因此您需要将 worker 设置为内联,使用 webpack 构建所有内容并运行测试。 你试过github.com/developit/jsdom-worker 吗?这适用于普通工人。我不确定使用worker-loader 导入模块的代码。 【参考方案1】:

如果不需要解析路径,可以使用"moduleNameMapper"忽略导入。

首先,创建一个包含export default '' 的空模块。

接下来,将以下内容添加到您的package.json

"jest": 
    "moduleNameMapper": 
        "^worker-plugin/loader.+$": "<rootDir>/EmptyModule"
    

【讨论】:

【参考方案2】:

这个solution 为我工作。

在一个名为__mocks__的文件夹中创建一个带有你需要的模拟实现的workerMock.js文件(当然你可以在任何你喜欢的地方创建它):

module.exports = Object.create(null);

然后在您的笑话配置中添加以下配置:

"moduleNameMapper": 
  "\\.worker.js":"<rootDir>/__mocks__/workerMock.js"

【讨论】:

【参考方案3】:

根据cpojer,Jest 不支持网络工作者。你应该使用模拟,阅读更多here

【讨论】:

为了被选为答案,您确实需要提供有效的解决方案。【参考方案4】:

这种方法对我来说适用于内联样式和配置样式的 worker 导入。

Jest 还不支持 Webpack 捆绑的 WebWorkers(我不知道),所以你必须模拟工作人员。只需将 worker 的功能提取到外部文件,然后在 worker 文件中执行 worker-y 位。

@WORKERS/imageInfo.js — 你的工人的“肉”:

export default imageInfoFunction(data) 
    //...

@WORKERS/imageInfo.worker.js,工人肉汁:

import imageInfoFunction from "./imageInfo";

self.onmessage = async function (e) 
  self.postMessage(imageInfoFunction(e.data));
;

通过这种方式,您可以在测试实际功能的同时仅模拟实现的 Worker 部分:

mocks/imageInfo.worker.js

import imageInfoFunction from "@WORKERS/imageInfo";

export default class ImageInfoWorker 
  constructor() 
    // should be overwritten by the code using the worker
    this.onmessage = () =>  ;
  

  // mock expects data:   instead of e:  data:   
  postMessage(data) 
    // actual worker implementation wraps argument into  data: arg ,
    // so the mock needs to fake it 
    this.onmessage( data: imageInfoFunction (data) );
  

现在在jest.config.js:

module.exports = 
  moduleNameMapper: 
    "@WORKERS/(.*\\.worker\\.js)$": "<rootDir>/mocks/$1",
    "@WORKERS/(.*)$": "<rootDir>/js/workers/$1",
  ,
;

请注意,我没有包含内联 worker-loader 配置,但我跳过了 ^(.*)。这是可行的,因为我们不再需要worker-loader,因为我们正在嘲笑工人。第一个路径是我们要模拟的 .worker.js 文件,另一个是我们要测试的实际功能。以下方法也可以:

    "^(.*?)@WORKERS/(.*\\.worker\\.js)$": "<rootDir>/mocks/$2",
    "^(.*?)@WORKERS/(.*)$": "<rootDir>/js/workers/$2",

这个解决方案可能会被推广,这样所有的工人都会被立即嘲笑,欢迎提出建议。

【讨论】:

我的@WORKERS/imageInfo.worker.js 也有 self.importScripts ,但它没有被嘲笑,知道如何解决它吗?所以我的@Workers/imageInfo.worker.js 看起来像 import imageInfoFunction from "./imageInfo"; self.importScripts("somescript"); self.onmessage = 异步函数 (e) self.postMessage(imageInfoFunction(e.data)); ;

以上是关于在 Jest 测试中使用 webpack 的 worker-loader 解析导入的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Jest 测试中使用我的 webpack 的 html-loader 导入?

使用 Jest 和 Webpack 别名进行测试

使用 webpack 配置运行 Jest 测试

我无法通过 symfony/webpack-encore 使用 Jest 和 Vuejs 运行测试

如何同时观看运行 Jest 测试的 webpack-dev-server?

使用 webpack-hot-middleware 配置环境时,Jest 测试失败