Skip to content

Unable to set target for Web Workers #17512

Open

Description

@kingller

Bug report

What is the current behavior?

Unable to set target for Web Workers

new Worker(new URL('./worker.js', import.meta.url));

My worker uses the package named decode-named-character-reference, the package exports as bellow,

"exports": {
    ".": {
      "deno": "./index.js",
      "react-native": "./index.js",
      "worker": "./index.js",
      "browser": "./index.dom.js",
      "default": "./index.js"
    }
  }

When I compile my website with webpack, the target is to use Defaults to browserslist, and it compile my web worker use its exports "browser": "./index.dom.js", the error happens ReferenceError: document is not defined.

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?

How can I set my web worker's target to webworker separately?
I want to compile the package named decode-named-character-reference use its exports "worker": "./index.js", then it can work well.

Other relevant information:
webpack version: 5.73.0
Node.js version: 14.20.0
Operating System: macOS Big Sur
Additional tools: VS code

Activity

  1. changed the title [-]Unable to set the target for Web Workers[/-] [+]Unable to set target for Web Workers[/+] on Jul 20, 2023
  2. webpack-bot commented on Oct 19, 2023

    @webpack-bot
    Contributor

    This issue had no activity for at least three months.

    It's subject to automatic issue closing if there is no activity in the next 15 days.

  3. added
    status: staleNo author response after a needs: request; close candidate
    on Oct 19, 2023
  4. webpack-bot commented on Nov 3, 2023

    @webpack-bot
    Contributor

    Issue was closed because of inactivity.

    If you think this is still a valid issue, please file a new issue with additional information.

  5. removed
    status: staleNo author response after a needs: request; close candidate
    on Dec 20, 2023
  6. moved this to Priority - Low in webpack 5/6on Dec 20, 2023
  7. added
    status: staleNo author response after a needs: request; close candidate
    on Mar 21, 2024
  8. removed
    status: staleNo author response after a needs: request; close candidate
    on Apr 5, 2024
  9. bastotec commented on Apr 7, 2024

    @bastotec

    I'm facing the same issue. Anyone else? Any workarounds?

  10. 8 remaining items

  11. added
    status: staleNo author response after a needs: request; close candidate
    on Jan 4, 2025
  12. removed
    status: staleNo author response after a needs: request; close candidate
    on Feb 4, 2025
  13. SurendraKumawat7742 commented on Apr 4, 2025

    @SurendraKumawat7742

    I want to resolve this problem.

  14. added
    status: staleNo author response after a needs: request; close candidate
    on Jul 4, 2025
  15. self-assigned this
    on Aug 29, 2025
  16. morijvan commented on Oct 6, 2025

    @morijvan

    Hi I am interested to work on this particular issue can you please assign this issue.

  17. vitonsky commented on May 13, 2026

    @vitonsky

    Hello everyone, what's progress on this?

    I see some activity related to that issue:

    The current state

    I just faced with the same problem on my project.

    I use latest webpack version, I have webpack config that build target: 'web'.

    My .ts file have code

    new Worker(
        /* webpackChunkName: "NotesImporter.worker" */ new URL(
            './NotesImporter.worker',
            import.meta.url,
        ),
        { type: 'module' },
    ),

    The worker is a .ts file that have import remark-stringify that is eventually import decode-named-character-reference and its package.json contains the following

      "exports": {
        "deno": "./index.js",
        "edge-light": "./index.js",
        "react-native": "./index.js",
        "worker": "./index.js",
        "workerd": "./index.js",
        "browser": "./index.dom.js",
        "default": "./index.js"
      },

    In our webpack config we have

    	resolve: {
    		byDependency: {
    			worker: {
    				conditionNames: ['worker', 'import', 'module', 'default'],
    			},
    		},
    	},
    

    so my expectations is:

    • Code for main thread builds well
    • WebWorker NotesImporter.worker.ts will be resolved via standard webpack rules
    • Any imports in file NotesImporter.worker.ts or its transitive imports will use config conditionNames: ['worker', 'import', 'module', 'default'] so package decode-named-character-reference will be resolved as decode-named-character-reference/index.js

    The actual behavior is:

    • Code for main thread builds well
    • The worker code throws error ReferenceError: document is not defined

    I've also tried update webpack config to

    	resolve: {
    		byDependency: {
    			esm: {
                    conditionNames: ['worker', 'import', 'module', 'browser'],
    			},
    		},
    	},
    

    It completely break our app:

    • No errors in runtime
    • Worker loads fine
    • The UI of our app looks broken. Probaby it's because UI frameworks load incorrect bundle.

    The question

    I just want to know about progress on this problem.

    If I miss something or you think I understand something wrong, please do correct me.

  18. alexander-akait commented on May 13, 2026

    @alexander-akait
    Member

    Please create reproducible test repo, it should work in most of cases, but yeah we still working on it, thanks

  19. hai-x commented on Jul 13, 2026

    @hai-x
    Member

    For now, you can work around this with layers: mark the worker's graph root via a dependency: "worker" rule, let the layer inherit transitively, and resolve that layer with the worker condition first.

    I also considered whether this belongs in webpack core. On closer look, the semantics of an automatic fix are more problematic than they seem.

    module.exports = {
    	// ...
          module: {
                  rules: [
                          // module created by `new Worker(new URL(...))` starts the worker layer
                          {
                                  dependency: "worker",
                                  layer: "worker",
                                  resolve: { conditionNames: ["worker", "..."] }
                          },
                          // everything transitively reached from it stays in that layer
                          {
                                  issuerLayer: "worker",
                                  resolve: { conditionNames: ["worker", "..."] }
                          }
                  ]
          }
    };

    We compared this exact scenario across bundlers (browser-target build, worker importing a package with worker/browser conditional exports, both directly and transitively):

    • rspack — bundles the worker into a separate chunk, but resolves its imports with the browser condition (same behavior as webpack).
    • turbopack — bundles the worker into a separate chunk group, also with the browser condition.
    • esbuild — doesn't bundle new Worker(new URL(...)) at all; the expression is left as-is in the output.
    • rolldown — same as esbuild, the worker request is not bundled.
  20. added theissue type on Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

help wantedMaintainers welcome a community PR for thisstatus: staleNo author response after a needs: request; close candidate

Type

Fields

Priority

None yet

Effort

None yet

Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions