parcel-bundler/parcel · error · ThrowableDiagnostic

import() is not allowed in ${asset.env.isWorklet() ? 'workle

Error message

import() is not allowed in ${asset.env.isWorklet() ? 'worklets' : 'service workers'}.

What it means

Thrown as a ThrowableDiagnostic when SWC reports a DynamicImport dependency inside an asset whose env is a worklet (asset.env.isWorklet()) or whose env.context === 'service-worker'. Dynamic import() is not supported in those contexts per the HTML spec, so Parcel refuses rather than emit broken output. The diagnostic includes a code frame at the import() and, if available, the original env creation site.

Source

Thrown at packages/transformers/js/src/JSTransformer.js:936

                  codeHighlights: [convertSourceLocationToHighlight(loc)],
                },
              ],
              hints: ['Try using a static `import`.'],
            };

            if (asset.env.loc) {
              diagnostic.codeFrames.push({
                filePath: asset.env.loc.filePath,
                codeHighlights: [
                  convertSourceLocationToHighlight(
                    asset.env.loc,
                    'The environment was originally created here',
                  ),
                ],
              });
            }

            throw new ThrowableDiagnostic({
              diagnostic,
            });
          }

          // If all of the target engines support dynamic import natively,
          // we can output native ESM if scope hoisting is enabled.
          // Only do this for scripts, rather than modules in the global
          // output format so that assets can be shared between the bundles.
          let outputFormat = asset.env.outputFormat;
          if (
            asset.env.sourceType === 'script' &&
            asset.env.shouldScopeHoist &&
            asset.env.supports('dynamic-import', true)
          ) {
            outputFormat = 'esmodule';
          }

          env = {

View on GitHub (pinned to 59484858a1)

Solutions

  1. Replace dynamic import() with a static `import` at the top of the worklet/service-worker file.
  2. If conditional code loading is required, split into separate service-worker bundles and import them via importScripts() (service workers) or the worklet's addModule() API.
  3. Move the lazily loaded logic into the main thread and message the worker instead.

Example fix

// before (service-worker.js)
self.addEventListener('install', () => {
  import('./feature').then(m => m.register());
});

// after
import {register} from './feature';
self.addEventListener('install', () => register());
Defensive patterns

Strategy: validation

Validate before calling

// Lint source for dynamic import in worklet/service-worker modules
const DYNAMIC_IMPORT_RE = /\bimport\s*\(/;
function scanForDynamicImport(sources) {
  return sources.filter(s => /(?:service-?worker|worklet)/i.test(s.path) && DYNAMIC_IMPORT_RE.test(s.code));
}

Prevention

When it happens

Trigger: Source code in a worklet (e.g. AudioWorklet, CSS Layout/Worklet) or a service-worker module contains a dynamic `import()` expression. SWC flags the dependency as kind DynamicImport, and the JS transformer checks the env before codegen.

Common situations: Service-worker code that lazily imports modules; AudioWorklet processors using import(); migration from a bundler that silently polyfilled dynamic import in workers.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/84342e2f52277547. Report an issue: GitHub.