fix(core): load the config as ESM in CommonJS projects - #69
Merged
Merged
Conversation
A project that declares `"type": "commonjs"` makes Node read a `.ts` config as CommonJS with module syntax detection off, so `export default` failed and the CLI and the bundler plugin could not load the config at all. The loader now evaluates project TypeScript in the config graph as ESM, and its message includes the failure it caught, which bundlers showed only as a config path.
🦋 Changeset detectedLatest commit: 38f13e5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
cssforge | 38f13e5 | Commit Preview URL Branch Preview URL |
Sep 24 2026, 01:47 PM |
Forcing the ESM format for every project TypeScript file also hit the package's own sources when they run from source, which broke the JSR smoke test under Deno. The override now applies only when the nearest package.json declares CommonJS and the file is written as ESM, so a Deno run, a `"type": "module"` project, and a CommonJS-authored config all keep their own format.
Hebilicious
added a commit
that referenced
this pull request
Sep 24, 2026
Cleans up the loader change in #69, which worked but did more than it needed to. `packages/cssforge/src/loader.ts` no longer walks package.json files, parses them, or guesses the module system from source text. It asks Node for the format Node chose and overrides only `commonjs-typescript`: ```ts const loaded = nextLoad(url, context); if (loaded.format !== "commonjs-typescript") return loaded; return { format: "module-typescript", source: loaded.source ?? readFileSync(fileURLToPath(parsed), "utf8"), shortCircuit: true, }; ``` That drops `packageTypeOf`, its cache, and the `usesEsmSyntax` regex, whose false positive silently switched a CommonJS-authored file to ESM, so 67 lines become 15 and the rule reads as one sentence: TypeScript in the config graph loads as ESM when Node would read it as CommonJS. Behavior change: a CommonJS-authored `.ts` module inside a CommonJS package now loads as ESM, matching the documented `export default` config shape. That is the trade for removing the heuristic, and the changeset says so. Also adds the review rule to AGENTS.md: a pull request is never merged without an explicit instruction for that pull request, release pull requests included. Verification: the loader test now covers `"type": "commonjs"`, `"type": "module"`, and an absent type field, and fails when the load hook is removed; `cssforge:test`, `typecheck`, `format`, `readme-check`, and `jsr-dry-run` pass; the JSR smoke passes with `--require-deno`; the example browser suite passes 5/5; and a Vite project built against locally packed 0.8.1 plus the plugin emits the tokens under all three type fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes a config load failure reported after 0.8.0 shipped.
A project whose package.json declares
"type": "commonjs"makes Node evaluatecssforge.config.tsas CommonJS with module syntax detection turned off, so the documentedexport default defineConfig({...})failed and neither the CLI nor the bundler plugin could load the config. Reproduced against the published 0.8.0 with a Vite build:[cssforge] Could not load virtual:cssforge.css: Could not load the CSS Forge config at ..., no CSS emitted.The loader now evaluates project TypeScript in the config graph as ESM, so the config format no longer depends on the consumer's
typefield. Its message also includes the failure it caught, which bundlers previously hid behind the config path.Verification: a
"type": "commonjs"Vite project builds and emits the tokens with the fix, and fails without it;cssforge:test,typecheck,format,readme-check, andjsr-dry-runpass. The regression test fails when the new load hook is removed.