如果我使用 ts-jest 和 webpack node.js api,Jest 检测到以下 1 个打开的句柄可能会阻止 Jest 退出

Jest has detected the following 1 open handle potentially keeping Jest from exiting if I use ts-jest and webpack node.js api

尝试使用 webpack node.js API 为 webpack 4 插件编写测试,但 1 条控制台消息困扰着我。这是我使用玩笑进行测试的简单代码:

webpack4.test.ts:

import path from 'path';
import webpack from 'webpack';

describe('webpack', () => {
  test('should pass with simplest config', (done) => {
    const compiler = webpack({
      mode: 'none',
      entry: path.resolve(__dirname, 'entry.ts'),
    });

    compiler.run((err, stats) => {
      if (err) {
        throw new Error(err.message);
      }

      expect(2).toBe(2);
      done();
    });
  });
});

entry.ts:

const b = 1;

如果我 运行 此代码在控制台中使用 jest,它会通过,会创建捆绑文件,但会显示一条警告消息:

A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks.

如果我 运行 开玩笑 --detectOpenHandles,则会显示另一条消息。

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

● 超时

  12 |       if (err) {
  13 |         throw new Error(err.message);
> 14 |       }
     |        ^
  15 |
  16 |       expect(2).toBe(2);
  17 |       done();

  at go$readFile (node_modules/graceful-fs/graceful-fs.js:118:14)
  at Object.readFile (node_modules/graceful-fs/graceful-fs.js:115:12)
  at Storage.provide (node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:90:3)
  at CachedInputFileSystem.readFile (node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:269:25)
  at CachedInputFileSystem._readJson (node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:223:10)
  at Storage.provide (node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:90:3)
  at CachedInputFileSystem.readJson (node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:273:25)
  at node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:22:26
  at forEachBail (node_modules/enhanced-resolve/lib/forEachBail.js:14:3)
  at findDescriptionFile (node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:17:3)
  at Object.loadDescriptionFile (node_modules/enhanced-resolve/lib/DescriptionFileUtils.js:74:4)
  at node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:24:27
  at AsyncSeriesBailHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:22:1)
  at AsyncSeriesBailHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at Resolver.doResolve (node_modules/enhanced-resolve/lib/Resolver.js:282:16)
  at node_modules/enhanced-resolve/lib/ParsePlugin.js:28:14
  at AsyncSeriesBailHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
  at AsyncSeriesBailHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at Resolver.doResolve (node_modules/enhanced-resolve/lib/Resolver.js:282:16)
  at node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:36:14
  at AsyncSeriesBailHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
  at AsyncSeriesBailHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at Resolver.doResolve (node_modules/enhanced-resolve/lib/Resolver.js:282:16)
  at Resolver.resolve (node_modules/enhanced-resolve/lib/Resolver.js:170:15)
  at Array.<anonymous> (node_modules/webpack/lib/NormalModuleFactory.js:208:22)
  at arrayEachFunc (node_modules/neo-async/async.js:2517:19)
  at Object.parallel (node_modules/neo-async/async.js:6858:9)
  at node_modules/webpack/lib/NormalModuleFactory.js:191:13
  at node_modules/webpack/lib/NormalModuleFactory.js:129:4
  at node_modules/webpack/lib/NormalModuleFactory.js:400:5
  at AsyncSeriesWaterfallHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
  at AsyncSeriesWaterfallHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at NormalModuleFactory.create (node_modules/webpack/lib/NormalModuleFactory.js:381:28)
  at node_modules/webpack/lib/Compilation.js:1063:18
  at Semaphore.acquire (node_modules/webpack/lib/util/Semaphore.js:29:4)
  at Compilation._addModuleChain (node_modules/webpack/lib/Compilation.js:1062:18)
  at Compilation.addEntry (node_modules/webpack/lib/Compilation.js:1164:8)
  at node_modules/webpack/lib/SingleEntryPlugin.js:46:17
  at AsyncParallelHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
  at AsyncParallelHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at node_modules/webpack/lib/Compiler.js:669:20
  at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
  at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at Compiler.compile (node_modules/webpack/lib/Compiler.js:662:28)
  at node_modules/webpack/lib/Compiler.js:321:11
  at Compiler.readRecords (node_modules/webpack/lib/Compiler.js:529:11)
  at node_modules/webpack/lib/Compiler.js:318:10
  at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
  at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at node_modules/webpack/lib/Compiler.js:315:19
  at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
  at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
  at Compiler.run (node_modules/webpack/lib/Compiler.js:312:24)
  at Object.<anonymous> (test/plugins/webpack4.test.ts:14:18)

看来我遗漏了一些东西,但我不知道,如果这条消息是什么原因,需要你的帮助。谢谢!

我认为这是因为您抛出错误但从未调用 done() 因为没有在任何地方捕获异常。

在第 13 行的 throw 语句之前,添加一个

fail('compiler.run() failed')
done()

经过大量实验后,我找到了一个简单的决定,这对我有帮助(500 毫秒对我的环境来说不够):

afterAll(async () => {
  // avoid jest open handle error
  await new Promise(resolve => setTimeout(() => resolve(''), 1000));
});