Skip to content

fix(nextjs-integration): make turbopack ENV inlining string/comment-safe#860

Merged
theoephraim merged 3 commits into
mainfrom
nextjs-turbopack-safe-inline
Jul 4, 2026
Merged

fix(nextjs-integration): make turbopack ENV inlining string/comment-safe#860
theoephraim merged 3 commits into
mainfrom
nextjs-turbopack-safe-inline

Conversation

@theoephraim

@theoephraim theoephraim commented Jul 4, 2026

Copy link
Copy Markdown
Member

What

The turbopack loader's static replacement of non-sensitive ENV.KEY references was a plain regex String.replace over the whole source, so matches inside string literals, comments, and template literal text got spliced with the quoted value — e.g. console.log("ENV.PUBLIC_VAR is set") became invalid JS.

Replacement is now AST-based, reusing the vite integration's replacement machinery:

  • createReplacerTransformFn moved from @varlock/vite-integration into @env-spec/utils/ast-replacer (generalized to take any estree-compliant parse fn instead of rollup's plugin context); the vite integration now imports it from there — no behavior change on the vite side.
  • The nextjs turbopack loader parses each file with @babel/parser (plugins picked per file extension) and replaces only real ENV.KEY member expressions. String literals, comments, template literal quasis, JSX text, nested members like foo.ENV.KEY, and longer identifiers like ENV.KEY_LONGER are left untouched; ${ENV.KEY} interpolations still inline.
  • If a file fails to parse (exotic syntax), the loader warns once per file and falls back to the previous regex replacement so values still inline.

Webpack is untouched (it uses DefinePlugin, which was already safe), and the recent turbopack gating is preserved: dev-mode server files still skip inlining in favor of runtime proxy reads, while client components, edge files, and all build-mode files still inline.

Testing

  • New unit tests for the loader (packages/integrations/nextjs/test/loader.test.ts) covering strings, comments, template literals, JSX text, member expressions, longer identifiers, sensitive skipping, the parse-failure fallback, and the dev/build/client/edge inlining gate.
  • Framework-test fixture coverage: the client-page fixture now renders ENV.PUBLIC_VAR inside a string literal, template-literal text, and JSX text, and the build scenarios assert the text survives verbatim into the prerendered HTML (guards both the turbopack AST path and webpack's DefinePlugin path end-to-end).
  • Framework tests pass locally: nextjs v14/v15/v16 suites and the full vite suite (since its replacement code moved).

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

bumpy-frog

The changes in this PR will be included in the next version bump.

patch Patch releases

  • @varlock/astro-integration 1.1.0 → 1.1.1 (cascade)
  • @varlock/cloudflare-integration 1.2.0 → 1.2.1 (cascade)
  • @varlock/nextjs-integration 1.1.3 → 1.1.4
  • @varlock/vite-integration 1.2.0 → 1.2.1

Bump files in this PR

Click here if you want to add another bump file to this PR


This comment is maintained by bumpy.

@pkg-pr-new

pkg-pr-new Bot commented Jul 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/varlock@860
npm i https://pkg.pr.new/@varlock/nextjs-integration@860
npm i https://pkg.pr.new/@varlock/vite-integration@860

commit: b6c78bc

@theoephraim theoephraim merged commit 73be93d into main Jul 4, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant