vite icon indicating copy to clipboard operation
vite copied to clipboard

Importing a file from a web worker that imports said web worker causes Vite to build forever

Open hf02 opened this issue 3 years ago โ€ข 20 comments

Describe the bug

I have my project set up where I have an index file that exports everything in the folder. This is so I can solve a circular dependency.

When I created a web worker, I had it import from the index file. One of these files in the index directly imported the web worker using ?worker. This worked fine in development. When I went to build, however, Vite seemed to get stuck in an infinite loop and only stopped when it ran out of memory.

Reproduction

~~https://github.com/hf02/vite-infinite-build~~ Much simpler reproduction, thanks to @zxch3n: https://stackblitz.com/edit/vitejs-vite-u59lcw?file=worker.js

System Info

System:
    OS: Windows 10 10.0.22000
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 9.38 GB / 15.95 GB
  Binaries:
    Node: 16.14.0 - ~\AppData\Local\nvs\default\node.EXE
    npm: 8.3.1 - ~\AppData\Local\nvs\default\npm.CMD
  Browsers:
    Edge: Spartan (44.22000.120.0), Chromium (98.0.1108.56)
    Internet Explorer: 11.0.22000.120

Used Package Manager

pnpm

Logs

PS C:\Users\user\Desktop\vite-project> # i replaced my windows username with a generic "user"
PS C:\Users\user\Desktop\vite-project> pnpx vite build --debug
  vite:config no config file found. +0ms
  vite:config using resolved config: {
  vite:config   root: 'C:/Users/user/Desktop/vite-project',
  vite:config   base: '/',
  vite:config   mode: 'production',
  vite:config   configFile: undefined,
  vite:config   logLevel: undefined,
  vite:config   clearScreen: undefined,
  vite:config   build: {
  vite:config     target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     polyfillModulePreload: true,
  vite:config     outDir: 'dist',
  vite:config     assetsDir: 'assets',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     cssTarget: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     sourcemap: false,
  vite:config     rollupOptions: {},
  vite:config     minify: 'esbuild',
  vite:config     terserOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: null,
  vite:config     manifest: false,
  vite:config     lib: false,
  vite:config     ssr: false,
  vite:config     ssrManifest: false,
  vite:config     reportCompressedSize: true,
  vite:config     chunkSizeWarningLimit: 500,
  vite:config     watch: null,
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }
  vite:config   },
  vite:config   configFileDependencies: [],
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     build: {}
  vite:config   },
  vite:config   resolve: { dedupe: undefined, alias: [ [Object], [Object] ] },
  vite:config   publicDir: 'C:\\Users\\user\\Desktop\\vite-project\\public',
  vite:config   cacheDir: 'C:\\Users\\user\\Desktop\\vite-project\\node_modules\\.vite',
  vite:config   command: 'build',
  vite:config   isProduction: true,
  vite:config   plugins: [
  vite:config     'alias',
  vite:config     'vite:modulepreload-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html-inline-proxy',
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:worker-import-meta-url',
  vite:config     'vite:asset',
  vite:config     'vite:define',
  vite:config     'vite:css-post',
  vite:config     'vite:watch-package-data',
  vite:config     'vite:build-html',
  vite:config     'commonjs',
  vite:config     'vite:data-uri',
  vite:config     'rollup-plugin-dynamic-import-variables',
  vite:config     'vite:asset-import-meta-url',
  vite:config     'vite:build-import-analysis',
  vite:config     'vite:esbuild-transpile',
  vite:config     'vite:terser',
  vite:config     'vite:reporter',
  vite:config     'vite:load-fallback'
  vite:config   ],
  vite:config   server: {
  vite:config     preTransformRequests: true,
  vite:config     fs: { strict: true, allow: [Array], deny: [Array] }
  vite:config   },
  vite:config   preview: {
  vite:config     port: undefined,
  vite:config     strictPort: undefined,
  vite:config     host: undefined,
  vite:config     https: undefined,
  vite:config     open: undefined,
  vite:config     proxy: undefined,
  vite:config     cors: undefined,
  vite:config     headers: undefined
  vite:config   },
  vite:config   env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     hasWarned: false,
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     warnOnce: [Function: warnOnce],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen],
  vite:config     hasErrorLogged: [Function: hasErrorLogged]
  vite:config   },
  vite:config   packageCache: Map(0) { set: [Function (anonymous)] },
  vite:config   createResolver: [Function: createResolver],
  vite:config   optimizeDeps: {
  vite:config     esbuildOptions: { keepNames: undefined, preserveSymlinks: undefined }
  vite:config   },
  vite:config   worker: {
  vite:config     format: 'iife',
  vite:config     plugins: [
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object],
  vite:config       [Object], [Object], [Object]
  vite:config     ],
  vite:config     rollupOptions: {}
  vite:config   }
  vite:config } +5ms
vite v2.8.4 building for production...
transforming (85241) src\lib\worker\theWorker.ts
<--- Last few GCs --->

[1580:000002AACF9E4580]   152266 ms: Mark-sweep 3980.6 (4139.2) -> 3968.6 (4141.2) MB, 1286.2 / 0.0 ms  (average mu = 0.131, current mu = 0.080) task scavenge might not succeed
[1580:000002AACF9E4580]   153712 ms: Mark-sweep 3982.3 (4141.4) -> 3970.8 (4143.4) MB, 1333.3 / 0.0 ms  (average mu = 0.105, current mu = 0.078) task scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 00007FF63F237B7F v8::internal::CodeObjectRegistry::~CodeObjectRegistry+114079
 2: 00007FF63F1C4546 DSA_meth_get_flags+65542
 3: 00007FF63F1C53FD node::OnFatalError+301
 4: 00007FF63FAFB29E v8::Isolate::ReportExternalAllocationLimitReached+94
 5: 00007FF63FAE587D v8::SharedArrayBuffer::Externalize+781
 6: 00007FF63F988C4C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1468
 7: 00007FF63F9958F9 v8::internal::Heap::PublishPendingAllocations+1129
 8: 00007FF63F9928CA v8::internal::Heap::PageFlagsAreConsistent+2842
 9: 00007FF63F985529 v8::internal::Heap::CollectGarbage+2137
10: 00007FF63F935A95 v8::internal::IndexGenerator::~IndexGenerator+22165
11: 00007FF63F15607F std::basic_ostream<char,std::char_traits<char> >::operator<<+80079
12: 00007FF63F154896 std::basic_ostream<char,std::char_traits<char> >::operator<<+73958
13: 00007FF63F29708B uv_async_send+331
14: 00007FF63F29681C uv_loop_init+1292
15: 00007FF63F2969BA uv_run+202
16: 00007FF63F265825 node::SpinEventLoop+309
17: 00007FF63F17CE83 v8::internal::Isolate::stack_guard+53827
18: 00007FF63F1FA40C node::Start+220
19: 00007FF63F01894C RC4_options+348236
20: 00007FF64007FE68 v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+14472
21: 00007FF9B1D354E0 BaseThreadInitThunk+16
22: 00007FF9B360485B RtlUserThreadStart+43
PS C:\Users\user\Desktop\vite-project>

Validations

hf02 avatar Feb 21 '22 06:02 hf02

i have nearly the same problem and wondering if anyone has a workaround in mind...

gotjoshua avatar Mar 16 '22 10:03 gotjoshua

I found a partial workaround to at least prevent the infinite loop and get a build output:

in vite.config.ts :

build: {
    commonjsOptions: {
      dynamicRequireTargets: [
        'src/MyWebWorker.ts',
      ],
    },
},
...

this avoids the loop during the transforming step, but does not transpile the webworker. rather it creates a single line file with

require("/Absolute/Pathto/src/MyWebWorker.ts");

gotjoshua avatar Mar 16 '22 12:03 gotjoshua

I have a simplified reproduction of this infinite build https://stackblitz.com/edit/vitejs-vite-oqqjnr?file=worker.js,main.js,package.json&terminal=dev

zxch3n avatar May 10 '22 10:05 zxch3n

I have a simplified reproduction of this infinite build https://stackblitz.com/edit/vitejs-vite-oqqjnr?file=worker.js,main.js,package.json&terminal=dev

Thanks for the much simpler reproduction. However, this may be a different bug? Instead of Vite showing transforming (1) worker.js and counting, it gets stuck on it.

I forked your project. using import() in worker.js instead. This fully reproduces the bug: https://stackblitz.com/edit/vitejs-vite-u59lcw?file=worker.js

hf02 avatar May 10 '22 12:05 hf02

I forked your project. using import() in worker.js instead. This fully reproduces the bug: https://stackblitz.com/edit/vitejs-vite-u59lcw?file=worker.js

I guess they are the same under the hook after this change

https://github.com/vitejs/vite/blob/77865b44b2f69642ca106716f6208a812cab9c24/packages/vite/CHANGELOG.md?plain=1#L444

zxch3n avatar May 10 '22 12:05 zxch3n

Any update?

iamcco avatar Jun 28 '22 14:06 iamcco

I also ran into this while trying to create a single file typed web worker. https://stackblitz.com/edit/vitejs-vite-9zt7v2?file=src/worker.ts

It works in dev but goes into a infinite loop during build.

What I was trying to do is build something like https://nodejs.org/api/worker_threads.html, where the script for both the client and the worker can be in the same file.

This is desirable in TypeScript in order align the type of data passed into the worker from the client.

Before this gets resolved, I now have to split up my worker into multiple files.

Pyrolistical avatar Aug 18 '22 20:08 Pyrolistical

I am running into the same issue. This is particularly in a Vue project and my initial solve was to use inversion of control by having the module which was originally calling new Worker (let's call it useWorker.ts) have a configurable member that creates the worker. Basically, useWorker.ts exports a function called setWorkerDefinition which looks something like:

let ModuleWorkerDefinition;

export function setWorkerDefinition(workerDefinition: () => Worker) {
    ModuleWorkerDefinition = workerDefinition;
} 

So that when something needs to create a worker it calls a method, call it useWorker, that can use ModuleWorkerDefinition. Something like:

export function useWorker() {
   return ModuleWorkerDefinition();
}

And lastly the new Worker call is abstracted out into a separate module, call it defineWorker.ts:

// some import that causes your circular dependency issue because it in turn somewhere imports `useWorker.ts`
import { setWorkerDefinition } from '@/useWorker';

setWorkerDefinition(() => {
    return new Worker(/* worker stuff here  */);
})

This means that useWorker.ts doesn't have to import the definite of a worker (which, in my case, imports some other things that were causing the circular dependency since some of those things ultimately imported useWorker.ts). So then the last step was to get something to import defineWorker.ts so that it would register itself.

In Vue this was pretty easy. In the main.ts for the app I just added a import '@/defineWorker.ts'; which took care of everything (since nothing imports main.ts in my app and it will definitely always be called). The trouble is now I have a need to nest workers and I think that the only solution I can come to is to have two different "worker entry files" so that they shouldn't end up importing each other, but that still feels super brittle to me. Is there actually any hope of a real solution to this? Because at the end of the day it works fine in dev mode add just fails when it is being bundled, which tells me that there isn't actually a circular dependency to be concerned about.

john-landgrave avatar Nov 02 '22 19:11 john-landgrave

In talking through this with one of my teammates I think it makes sense why this is happening. Can someone confirm that this is how the bundler is working and that this logic makes sense? It seems to us that this is about the way that the bundler should be working:

  1. Start compiling the entry file
  2. Trace dependencies and build and start building an AST of the dependency network for the entry file
  3. When a worker import is encountered, start a sub-process at step 1 for that file
  4. Continue through the process from the "main entry file" until you are done.
  5. Either in a separate thread or after the "main entry file" is done, finish tracing dependencies and bundling for the worker file.

I understand that there is a lot more to the process here, but as a whiteboard explanation of the process, I think that this is pretty close to what it seems to be doing? If that is the case, then assuming that there is some process/memory isolation in step 3 it would make sense that the circular loop would case the cycle to repeat over and over until you run out of memory. However, it seems like a reasonable solution to essentially create a dictionary where the keys are the import paths and the values are the files that will ultimately be created so that you can effectively reuse the output of the sub-process spawned in step 3 at any import, even if that import is inside of the worker itself, right? Because in the end this is going to show up in the bundled, transpiled, minified code as new Worker('/some-worker.8675309.js'), right?

Is this something that it would even be possible to write a Vite/Rollup plugin for, or is this just too core to the way that those tools work?

john-landgrave avatar Nov 02 '22 19:11 john-landgrave

I had the same issue, and have found a workaround after attempting for several days. Hope this can help someone.

The key idea is forcing the vite bypassing new Worker/SharedWorker(...)

let scriptForWorker = "/path/to/myWorker.js"
const worker = new Worker(scriptForWorker, { type: 'module' })

The scriptForWorker is a true variable, so the vite have no idea about how to process it, and will just keep it as a simple string. And then, let rollup build the myWorker.js for us.

  1. modify vite.config, let rollup build 'myWorker.js'
  2. modify vite.config, let vite generate manifest.json
import { defineConfig } from 'vite';
export default defineConfig({
    build: {
        rollupOptions: {
            input: {
                main: "index.html",
                worker: "path/to/worker"
            }
        },
        manifest: true
    }
});
  1. modify the source code about new Worker(...)
let scriptForWorker = "path/to/worker.ts";
if(!import.meta.env.DEV){
    // in production, we get the js from manifest.json
    // in `npm run dev` mode, using orignal path directly
    const response = await fetch("/manifest.json");
    if(response.ok){
        const manifest = await response.json();
        scriptForWorker = manifest[scriptForWorker].file;
    }
    else{
        return Promise.reject(response.statusText);
    }
}

// create the Worker
const worker = new Worker(scriptForWorker, { type:'module' });
// or the SharedWorker
const sharedWorker = new SharedWorker(scriptForWorker, { type:'module' });
  1. building
npm run build
# or
npm run dev

AceBear avatar Nov 06 '22 10:11 AceBear

We had the exact same case (worker -> importing file -> importing same worker). However, instead of hanging, we got:

Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
...

deluksic avatar Feb 09 '23 12:02 deluksic

we also get this hang. any update? Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:

dkspec avatar Apr 09 '23 09:04 dkspec

From the error logs, it seems that this happens from trying to bundle workers as CommonJS?

Would the error go away if worker constructor files were instead just treated as entry points for ESM bundling? That's basically how Vite works in dev, and how I used to assume Vite built code as well.

I understand that some apps will want backwards compat through opt-in or opt-out, but all modern browsers and runtimes support module workers.

lgarron avatar Oct 06 '23 22:10 lgarron

I believe for a while the problem was masked by the nested workers regression (https://github.com/vitejs/vite/issues/13367). You can see this in other developer outputs above. The error would look like:

Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:

That issue was fixed in #14685 and released in v5.0.0-beta.11. The original reported issue is now present for nested workers and re-occuring from v5.0.0-beta.11.

After the next major release I think there will be an uptick in people reporting this hanging build issue as circular imports is a common pattern when working with nested workers (pun unintended) and often added automatically by dev tooling.

jamsinclair avatar Nov 08 '23 15:11 jamsinclair

This issue is still present in v5.0.0-beta.11. As mentioned in https://github.com/vitejs/vite/issues/14499#issuecomment-1740267849, it can be circumvented by doing:

Details
import { defineConfig } from 'vite';

// https://github.com/vitejs/vite/blob/ec7ee22cf15bed05a6c55693ecbac27cfd615118/packages/vite/src/node/plugins/workerImportMetaUrl.ts#L127-L128
const workerImportMetaUrlRE =
    /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g

// https://vitejs.dev/config/
export default defineConfig({
    build: {
        target: 'esnext',
    },
    server: {
        host: 'localhost',
        headers: {
            'Cross-Origin-Embedder-Policy': 'require-corp',
            'Cross-Origin-Opener-Policy': 'same-origin',
            'Cross-Origin-Resource-Policy': 'cross-origin'
        }
    },
    optimizeDeps: {
        esbuildOptions: {
            target: 'esnext'
        }
    },
    worker: {
        format: 'es',
        // https://github.com/vitejs/vite/issues/7015
        // https://github.com/vitejs/vite/issues/14499#issuecomment-1740267849
        plugins: () => [
            {
                name: 'Disable nested workers',
                enforce: 'pre',
                transform(code: string, id: string) {
                    if (code.includes('new Worker') && code.includes('new URL') && code.includes('import.meta.url')) {
                        return code.replace(workerImportMetaUrlRE, `((() => { throw new Error('Nested workers are disabled') })()`);
                    }
                }
            }
        ]
    }
});

Note that for Emscripten-generated code this would mean that the locateFile handler on the incoming module would have to be overridden to provide support for nested workers.

kleisauke avatar Nov 08 '23 16:11 kleisauke

I'd like to second @lgarron's idea for not separately bundling module workers. Seems like it would simplify many things. No need to worry about nested workers, parallelized builds, circular-ish dependencies and separate worker plugins. Plus reduced code duplication as modules can be shared between main entry points and module workers.

Are there any obvious or hidden pitfalls that would make this unappealing? @patak-dev @sapphi-red

Some smaller ones that I can think of are:

  • Vite users might be heavily relying on plugins to augment code differently between workers and their main code
  • Vite would still need to keep current worker tooling for legacy support of non-module workers

jamsinclair avatar Nov 08 '23 16:11 jamsinclair

I've attempted to create an experimental plugin that would make Vite chunk module workers instead of bundling. It seems to work for my use case and solves the circular dependency issue (Gist of plugin source).

There's a few caveats that showed up:

  • Only works for workers instantiated like new Worker(new URL('path', import.meta.url), type: { 'module' })
  • module preload will need to be disabled in your vite config. Otherwise preload code is injected into the worker which breaks it.
  • You need to be careful that the module that instantiates the worker does not bundle any code that includes Web APIs that are not supported by workers. As your worker will import that bundle and it could break.

There's likely other things that could break because the plugin simply tricks Vite into thinking the worker is a dynamic import of an ES module.

jamsinclair avatar Dec 04 '23 14:12 jamsinclair

for me it worked for opencv.js wasm workers with the config from https://github.com/vitejs/vite/issues/7015#issuecomment-1802213572 , thanks a lot!

simonbuehler avatar Dec 06 '23 10:12 simonbuehler

Fixing this may solve https://github.com/nuxt/nuxt/issues/22966

CodeF53 avatar Dec 08 '23 16:12 CodeF53

I'm having a similar problem. Simple web workers are fine, but any code that imports classes & instantiates a new object inside a web worker always fails.

wcdeich4 avatar Dec 26 '23 01:12 wcdeich4

While I appreciate a partial fix in https://github.com/vitejs/vite/pull/16103 , I'd like to note that that it does far from solving the issue in general.

Trying to run npx vite build using a build of eef9da13d0028161eacc0ea699988814f29a56e4 on my repro from https://github.com/vitejs/vite/issues/14499 still fails the same way, unfortunately.

https://github.com/vitejs/vite/pull/16103 states that:

But I think it's fine because doing that is not popular and will make the code complex.

I appreciate that it might not be possible to fix the current situation super easily, but it's not a matter of popular conventions. Some of us don't have a choice about the recursive dynamic imports in our code, unless we want our code to fail in other bundlers. ๐Ÿ˜ข

Would it be possible to reopen one of these issues to keep track of the general problem?

  • https://github.com/vitejs/vite/issues/7015 (this issue)
  • https://github.com/vitejs/vite/issues/14499
  • https://github.com/vitejs/vite/issues/15426

Thanks, ยปLucas

lgarron avatar Mar 06 '24 19:03 lgarron

@lgarron

I'd like to note that that it does far from solving the issue in general.

I do think it solves most cases. I actually tested with all the repros I found and all of them worked (without throwing errors on build) as I stated in the PR. Your repro does not match the "complex case" condition.

By using the main branch (eef9da13d0028161eacc0ea699988814f29a56e4) Vite and setting worker.format: 'es', the build of your repro (#14499) succeeds and the preview is working.

vite v5.1.5 building for production...
โœ“ 41 modules transformed.
dist/index.html                                                           0.45 kB โ”‚ gzip:   0.30 kB
dist/assets/chunk-KDMCYBSC-DJfxFAvj.js                                    1.56 kB  
dist/assets/twsearch-SLVE4NQH-CeABCLXd.js                                 2.04 kB  
dist/assets/search-worker-entry-Biyfh-f5.js                               4.81 kB  
dist/assets/search-dynamic-solve-sq1-INOYNRSJ-t49RGMrR.js                 7.77 kB  
dist/assets/search-dynamic-solve-kilominx-WREDL6AE-Ba_NcXDp.js            8.05 kB  
dist/assets/search-dynamic-solve-master_tetraminx-3D4MBF3V-DMwauRA8.js    8.12 kB  
dist/assets/search-dynamic-solve-fto-EY5ZVAGO-CWb6KctK.js                17.80 kB  
dist/assets/search-dynamic-sgs-unofficial-KTHSSINP-BR48LPsc.js           27.61 kB  
dist/assets/search-dynamic-solve-4x4x4-JQRNWKAG-BAd9vsD8.js              27.73 kB  
dist/assets/search-dynamic-sgs-side-events-KBQTGXZR-DA9PpCP1.js          31.42 kB  
dist/assets/index-XmOFflW_.js                                            70.31 kB  
dist/assets/inside-5CIAPTLP-DjKnNCQK.js                                  76.18 kB  
dist/assets/index-LDxwnHR4.css                                            1.24 kB โ”‚ gzip:   0.65 kB
dist/assets/inside-5CIAPTLP-BymCh4jE.js                                   0.10 kB โ”‚ gzip:   0.10 kB
dist/assets/search-worker-entry-BPdL309Z.js                               0.96 kB โ”‚ gzip:   0.55 kB
dist/assets/chunk-KDMCYBSC-DrFRfSNi.js                                    1.55 kB โ”‚ gzip:   0.71 kB
dist/assets/twsearch-SLVE4NQH-8_jTapat.js                                 2.21 kB โ”‚ gzip:   0.98 kB
dist/assets/search-dynamic-solve-sq1-INOYNRSJ-9KflgMA7.js                 7.72 kB โ”‚ gzip:   3.18 kB
dist/assets/search-dynamic-solve-kilominx-WREDL6AE-BWEa1P9Z.js            7.99 kB โ”‚ gzip:   3.28 kB
dist/assets/search-dynamic-solve-4x4x4-JQRNWKAG-BB_OirYQ.js              27.68 kB โ”‚ gzip:   9.62 kB
dist/assets/puzzles-dynamic-unofficial-WXH65MSQ-BfUzpykK.js              30.61 kB โ”‚ gzip:   3.85 kB
dist/assets/search-dynamic-sgs-side-events-KBQTGXZR-WehrTIpp.js          31.70 kB โ”‚ gzip:   6.59 kB
dist/assets/index-CvE7NQzx.js                                            70.25 kB โ”‚ gzip:  22.53 kB
dist/assets/index-BepD_N6A.js                                            90.43 kB โ”‚ gzip:  26.89 kB
dist/assets/puzzles-dynamic-side-events-EEMN2PI4-B1nZhrxY.js            118.69 kB โ”‚ gzip:  13.14 kB
dist/assets/twsearch-BDAXZGZU-Q2YC2EQ6-CCxkWTHd.js                      418.70 kB โ”‚ gzip: 166.31 kB
โœ“ built in 2.30s

image

If it doesn't work on your computer, there's probably something wrong with your self-built Vite. If not, maybe there's a bug that doesn't happen on my computer?

sapphi-red avatar Mar 07 '24 10:03 sapphi-red

By using the main branch (eef9da1) Vite and setting worker.format: 'es', the build of your repro (#14499) succeeds and the preview is working.

That's reassuring to hear!

I tried it again, and I still can't get it to work โ€” do you have more details on how to test?

This is what I'm doing:

# In a vite checkout:
pnpm i
pnpm run build
cd packages/vite
npm link

# In a project:
npm link vite

Regardless of what I try to put in vite.config.js, I now get:

> npx vite build src
vite v5.1.5 building for production...
โœ“ 33 modules transformed.
x Build failed in 622ms
error during build:
RollupError: [commonjs--resolver] Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.
file: /Users/lgarron/Downloads/fjlsdfjdsf/node_modules/cubing/dist/lib/cubing/chunks/chunk-44CBFEXI.js
    at error (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/parseAst.js:337:30)
    at validateOptionsForMultiChunkOutput (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:16926:16)
    at Bundle.generate (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:16819:17)
    at file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:19376:27
    at catchUnfinishedHookActions (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:18809:16)
    at bundleWorkerEntry (file:///Users/lgarron/Code/git/github.com/vitejs/vite/packages/vite/dist/node/chunks/dep-bykU6hf7.js:49118:61)
    at workerFileToUrl (file:///Users/lgarron/Code/git/github.com/vitejs/vite/packages/vite/dist/node/chunks/dep-bykU6hf7.js:49172:29)
    at Object.transform (file:///Users/lgarron/Code/git/github.com/vitejs/vite/packages/vite/dist/node/chunks/dep-bykU6hf7.js:49641:40)
    at transform (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:17368:16)
    at ModuleLoader.addModuleSource (file:///Users/lgarron/Code/git/github.com/vitejs/vite/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:17580:36)

lgarron avatar Mar 09 '24 20:03 lgarron

Aha! I forgot that the vite.config.js file needs to be in the src folder, not the project root! It works with:

export default {
  worker: {
    format: "es"
  }
}

๐Ÿคฉ๐Ÿคฉ๐Ÿคฉ

This is fantastic to see, but unfortunately it does mean people using our library will still get a confusing error out of the box. Given that ESM is the default output for the main bundles, would it be possible to default the workers to ESM as well? I would find that much more intuitive, and it could allow significant code deduplication for some use cases.

lgarron avatar Mar 09 '24 20:03 lgarron

would it be possible to default the workers to ESM as well?

We won't be able to do that for now. ESM workers are not supported by browsers we specify as the default value of build.target.

sapphi-red avatar Mar 10 '24 08:03 sapphi-red

would it be possible to default the workers to ESM as well?

We won't be able to do that for now. ESM workers are not supported by browsers we specify as the default value of build.target.

what about typescript?

wcdeich4 avatar Mar 11 '24 13:03 wcdeich4