Skip to content

fix(cli): ensure type:module before Vite loads vite.config.ts (fixes #184)#197

Open
yunus25jmi1 wants to merge 1 commit intocloudflare:mainfrom
yunus25jmi1:fix/issue-184-cloudflare-plugin-esm-require
Open

fix(cli): ensure type:module before Vite loads vite.config.ts (fixes #184)#197
yunus25jmi1 wants to merge 1 commit intocloudflare:mainfrom
yunus25jmi1:fix/issue-184-cloudflare-plugin-esm-require

Conversation

@yunus25jmi1
Copy link
Contributor

Problem

Projects without "type": "module" in package.json cause Vite to bundle vite.config.ts through esbuild's CJS path, producing a .vite-temp/*.timestamp.mjs file that contains require() calls for the imported plugins. On Node 22 in CI (GitHub Actions, ubuntu-latest), require()-ing a .mjs file is not supported and the build fails immediately:

failed to load config from /home/runner/work/.../vite.config.ts
Error: Dynamic require of "file:///…/@cloudflare/vite-plugin/dist/index.mjs" is not supported
    at file:///.../node_modules/.vite-temp/vite.config.ts.timestamp-xxx.mjs:5:9

The affected user had set up their project manually (without vinext init) or before the init step added "type": "module". vinext init already adds this field, but vinext dev / vinext build were not enforcing it.

Fix

Call ensureESModule(root) + renameCJSConfigs(root) in both the dev() and buildApp() CLI commands, before Vite is loaded. This reuses the same logic already used by vinext init.

  • renameCJSConfigs renames postcss.config.js / tailwind.config.js / .eslintrc.js etc. → .cjs first, preventing breakage in those files once "type": "module" is added
  • ensureESModule adds "type": "module" to package.json
  • Both are no-ops when the project is already correctly configured (no extra I/O on the hot path)
  • A warning is printed when a change is made, pointing users to run vinext init to make it permanent

Tests

9 new unit tests added to tests/deploy.test.ts under the describe block "ensureESModule + renameCJSConfigs — issue #184 compatibility":

  • Adds type:module when missing
  • Idempotent — safe to call multiple times
  • Returns false when no package.json exists
  • Renames CJS postcss.config.jspostcss.config.cjs before adding type:module
  • Skips rename for ESM-style postcss.config.js (no module.exports or require())
  • Renames tailwind.config.js when CJS
  • Renames .eslintrc.js when CJS
  • Renames CJS config that uses require() (not only module.exports)
  • Handles multiple CJS config files simultaneously

All 169 tests pass (pnpm exec vitest run tests/deploy.test.ts).

Fixes #184

…loudflare#184)

Projects that lack "type":"module" in package.json caused Vite to bundle
vite.config.ts through esbuild's CJS path, producing a .vite-temp/*.mjs file
that contains a CJS require() for @cloudflare/vite-plugin. On Node 22 in CI
(GitHub Actions ubuntu-latest), require()-ing an .mjs file is not supported
and the build fails with:

  Error: Dynamic require of "…/@cloudflare/vite-plugin/dist/index.mjs" is
  not supported

Fix: call ensureESModule(root) + renameCJSConfigs(root) in both the dev() and
buildApp() CLI commands, before Vite is loaded. This mirrors what vinext init
already does, but applies lazily for projects that were set up manually or
before the init step was introduced.

- renameCJSConfigs renames postcss.config.js / tailwind.config.js / .eslintrc.js
  etc. to .cjs first, to avoid breakage in those files after ESM mode is enabled
- ensureESModule adds "type":"module" to package.json
- Both are no-ops when the project is already correctly configured
- A warning is emitted when a change is made, pointing users to vinext init
- 9 new unit tests cover the full scenario including multi-file rename

Fixes cloudflare#184
@southpolesteve
Copy link
Collaborator

/bigbonk review

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 3, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vinext@197

commit: c67ef0d

@yunus25jmi1
Copy link
Contributor Author

@copilot The failing job encountered repeated 500 Internal Server Error responses from GitHub during git fetch operations, resulting in exit code 128. This is not an issue with your code or workflow configuration.

@yunus25jmi1
Copy link
Contributor Author

@southpolesteve @elithrar kindly review the changes.

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.

vinext build fails in CI (GitHub Actions): Dynamic require of @cloudflare/vite-plugin not supported in ESM context

2 participants