From 91ec382cc6d29d297352583a424261f1cdba1d96 Mon Sep 17 00:00:00 2001 From: Max B Date: Sat, 22 Aug 2026 11:14:24 +0200 Subject: [PATCH] fix(compiler): allow bare side-effect imports of ambient-only modules A bare `import "spec";` with no bound names of a module that exists only as an ambient `declare module` type surface has no runtime module and nothing bound from it for other code to observe, so dropping the statement is behaviorally exact. This is the standard shape of a bundler-only stylesheet import (`import "pkg/dist/style.css";`), which previously hard-errored with SC1010 like any other unsupported import. Bound imports of the same kind of module (`import styles from "x.css"`) still fence, since something would be missing. --- packages/compiler/src/frontend/program.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/compiler/src/frontend/program.ts b/packages/compiler/src/frontend/program.ts index 4dbe00a2..e4179bd0 100644 --- a/packages/compiler/src/frontend/program.ts +++ b/packages/compiler/src/frontend/program.ts @@ -2158,6 +2158,21 @@ function preflight7(load: LoadResult): { refuse(refusal.message, "%Error", ambientNote); continue; } + // A BARE side-effect import (`import "x";` — no default, named, or + // namespace binding: stmt.importClause is undefined) of a module + // that exists ONLY as an ambient 'declare module' type surface has + // no runtime module AND nothing bound from it for other code to + // reference — the two facts together make dropping the statement + // behaviorally exact, not an approximation. This is the standard + // shape of a bundler-only stylesheet import (`import + // "pkg/dist/style.css";`, ambient-declared via a `declare module + // "*.css"` surface): real CSS side effects don't exist in a + // compiled binary with no browser to apply them to, so there is + // nothing this program could have observed from the import + // succeeding that it can no longer observe. A bound import + // (`import styles from "x.css"`, `import { x } from "x"`) still + // fences below — something WOULD be missing. + if (stmt.importClause === undefined && ambientDeclared(spec)) continue; // Runtime-resolvable (or a shape the probe stays conservative // about) with no compilable types answer: scriptc's fence. diags.push(