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
- Replace dynamic import() with a static `import` at the top of the worklet/service-worker file.
- 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.
- 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
- Static-import everything at the top of worker/worklet modules.
- Add an ESLint override banning dynamic import in service-worker/worklet globs.
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.