Skip to content

import.meta.env.LEGACY broken due to esbuild's constant folding #1999

@jonaskuske

Description

@jonaskuske

⚠️ IMPORTANT ⚠️ Please check the following list before proceeding. If you ignore this issue template, your issue will be directly closed.

  • Read the docs.
  • Use Vite >=2.0. (1.x is no longer supported)
  • If the issue is related to 1.x -> 2.0 upgrade, read the Migration Guide first.

Describe the bug

Works:

console.log(import.meta.env.LEGACY)
// true or false depending on chunk

Doesn't work:

if (import.meta.env.LEGACY) {
  console.log(true)
} else {
  console.log(false)
}
// true in both chunks

esbuild runs before the value is replaced so it still sees the '__VITE_IS_LEGACY__' marker, then – even with minification disabled – does its constant folding aka dead code elimination. Because '__VITE_IS_LEGACY__' is truthy, the entire else branch is dropped and both the legacy and the modern chunk log true.

Likewise, this will only ever run the else branch because '__VITE_IS_LEGACY__' === true is folded into false:

if (import.meta.env.LEGACY === true) {
  console.log(true)
} else {
  console.log(false)
}

To fix this, you can use an array as marker because array and object expressions don't participate in constant folding: esbuild.github.io/api/#define

I've submitted a PR :)

Reproduction

See the updated playground/legacy/main.js that uses if/else branching – if you run it with the current plugin code from upstream, the test will fail.

System Info

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions