问题场景
在项目开发中需要利用Web Worker API来提高代码执行效率。在使用了Web Worker后进行项目打包时发现打包报错。
当时使用的vite 4.5.1版本,报错信息如下:
vite v4.5.1 building for production...
transforming (3556) node_modules\lodash-es\_baseSetToString.jsUnexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite:worker) transform "D:/projects/exceed/exceed-ui/src/pages/Workspace/components/runWorker.ts?worker"
error during build:
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite:worker) transform "D:/projects/exceed/exceed-ui/src/pages/Workspace/components/runWorker.ts?worker"
at process.handleBeforeExit (file:///D:/projects/exceed/exceed-ui/node_modules/rollup/dist/es/shared/node-entry.js:25902:28)
at Object.onceWrapper (node:events:632:26)
at process.emit (node:events:517:28)
解决过程
在vite的issues里找到了相似的问题。issue链接
同样使用了worker打包时报错,并且报错信息基本一致。但是我的代码并没有该issue里的用法: when using sqllite when I have workers in workers
但是看到该问题在vite 5.0版本已经被修复,就尝试将vite版本升级到5.0试试看。
在vite升级到5.0.11后尝试重新打包时,出现了新的问题,报错信息如下:
vite v5.0.11 building for production...
<--- Last few GCs --->
[25984:000001F950145410] 60415 ms: Mark-sweep 4023.2 (4135.1) -> 4012.0 (4139.3) MB, 1056.0 / 0.0 ms (average mu = 0.168, current mu = 0.044) allocation failure; scavenge might not succeed
[25984:000001F950145410] 62471 ms: Mark-sweep 4028.4 (4139.3) -> 4017.7 (4145.1) MB, 2014.7 / 0.0 ms (average mu = 0.076, current mu = 0.020) allocation failure; scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF7BD05194F node_api_throw_syntax_error+175855
2: 00007FF7BCFD6026 SSL_get_quiet_shutdown+59654
3: 00007FF7BCFD7D10 SSL_get_quiet_shutdown+67056
4: 00007FF7BDA821F4 v8::Isolate::ReportExternalAllocationLimitReached+116
5: 00007FF7BDA6D582 v8::Isolate::Exit+674
6: 00007FF7BD8EF41C v8::internal::EmbedderStackStateScope::ExplicitScopeForTesting+124
7: 00007FF7BD8EC63B v8::internal::Heap::CollectGarbage+3963
8: 00007FF7BD902873 v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath+2099
9: 00007FF7BD90311D v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath+93
10: 00007FF7BD9128E0 v8::internal::Factory::NewFillerObject+816
11: 00007FF7BD603325 v8::internal::DateCache::Weekday+1349
12: 00007FF7BDB1F751 v8::internal::SetupIsolateDelegate::SetupHeap+558193
13: 00007FF7BDB014C1 v8::internal::SetupIsolateDelegate::SetupHeap+434657
14: 00007FF73E0196F5
打包时出现了node堆栈溢出问题,但是当时项目并不是很大,理论上不会出现这个问题,本着试试看的态度将执行打包的node内存增大后尝试进行打包,发现依然没有解决问题(意料之中吧也算)
然后在vite的issues里又发现了相似报错的问题。issue链接
发现这个问题存在很久,也被人诟病很久了。产生这个问题的场景很多,有些可以通过增加node内存解决,有些则不行。
然后又针对这个问题做了个测试,写了一个简单的worker使用,发现打包时并没有问题,然后对比了项目中使用的worker特殊在哪里,后来发现worker和主线程的js文件做了循环引用。
//worker.js
import { RUNNER_STATUS, STEP_STATUS } from './runner'
//runner.js
import Worker from './worker.js?worker'
将循环引用修改去除后可以正常打包啦!