Skip to content

fix(compiler): allow bare side-effect imports of ambient-only modules - #198

Open
techfreaque wants to merge 1 commit into
vercel-labs:mainfrom
techfreaque:fix-ambient-css-noop
Open

fix(compiler): allow bare side-effect imports of ambient-only modules#198
techfreaque wants to merge 1 commit into
vercel-labs:mainfrom
techfreaque:fix-ambient-css-noop

Conversation

@techfreaque

Copy link
Copy Markdown

Problem

A bare side-effect import — import "somepackage/dist/style.css";, with
no default, named, or namespace binding — is a no-op in every JS runtime
that isn't asked to bundle CSS, including scriptc's own compiled
binaries (there is no browser to apply a stylesheet side effect to).
When the imported specifier resolves only to an ambient declare module "*.css" (or similarly-shaped) type surface — i.e. there is a type
declaration but no compilable runtime module behind it — the preflight
import-statement pass in packages/compiler/src/frontend/program.ts
still hard-errors on it:

error SC1010: the '<spec>' module (it exists only as an ambient 'declare
module' type surface — there is no runtime module to import) is not
supported yet

This is a near-universal pattern for any component library that ships
its own stylesheet, and it blocked the containing file from being
analyzed at all.

Root cause

The bare-import case was treated identically to a bound import (import x from "spec", import { x } from "spec") of the same kind of module.
For a bound import that's correct — the program expects a real binding
that doesn't exist. For a bare side-effect import, nothing is bound, so
there is nothing later code could observe being missing.

Fix

In preflight7 (packages/compiler/src/frontend/program.ts), before
the existing ambient-module fence fires for a bare import specifier that
resolves to types only, add a guard: if the import statement has no
import clause at all (stmt.importClause === undefined, i.e. a pure
import "spec";) and the specifier is only ambient-declared
(ambientDeclared(spec), an existing helper already used by this
function's diagnostic messages), skip the statement instead of fencing
it. Bound imports of the same module still fence exactly as before.

Verification

  • cd packages/compiler && node node_modules/typescript5/bin/tsc -p tsconfig.json — 0 errors.
  • Existing frontend/preflight test suites (packages/compiler/test/ts7,
    tests/harness/diagnostics.test.ts) pass identically before and after
    the change (compared against the unmodified base) — no regressions.
    The tests/diagnostics/pkg-import-fences fixture, which asserts bound
    ambient-module imports still fence, is unaffected since all its
    imports bind names.
  • Manual repro via the compiler's analyze() API: a declare module "*.css"; ambient declaration plus a bare import "foo/dist/style.css";
    now analyzes with zero diagnostics, while import styles from "foo/dist/style.css"; against the same declaration still produces the
    SC1010 diagnostic.

@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

@mabr-pcvisit is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

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.
@techfreaque
techfreaque force-pushed the fix-ambient-css-noop branch from 0e6d11e to 91ec382 Compare August 22, 2026 09:29
techfreaque added a commit to techfreaque/scriptc that referenced this pull request Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant