vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.56k stars 6.19k forks source link

Dev server is stateful in regards to env vars #17340

Open rschristian opened 5 months ago

rschristian commented 5 months ago

Describe the bug

Bit of a weird one, but the dev server seems to be stateful in its handling of env vars, in that you must access the the root (/) before the env vars are inserted into (say) a JS asset. This shouldn't happen, served assets shouldn't change depending on the order of access.

Note: Stackblitz seems to always redirect to / upon starting a dev server, or at least I couldn't figure out how to get it to not, hence the GitHub repo reproduction.

Reproduction

https://github.com/rschristian/bug__vite-env-vars

Steps to reproduce

  1. npm install && npm run dev
  2. navigate to http://localhost:5173/main.js
  3. Notice the returned asset looks like this:

/main.js

console.log(`vite mode: ${import.meta.env.MODE}`);
  1. navigate to http://localhost:5173
  2. navigate back to http://localhost:5173/main.js
  3. Notice the return asset looks like this:

/main.js


import.meta.env = {"BASE_URL": "/", "MODE": "development", "DEV": true, "PROD": false, "SSR": false};console.log(`vite mode: ${import.meta.env.MODE}`);

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1haW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0Lm1ldGEuZW52ID0ge1wiQkFTRV9VUkxcIjogXCIvXCIsIFwiTU9ERVwiOiBcImRldmVsb3BtZW50XCIsIFwiREVWXCI6IHRydWUsIFwiUFJPRFwiOiBmYWxzZSwgXCJTU1JcIjogZmFsc2V9O2NvbnNvbGUubG9nKGB2aXRlIG1vZGU6ICR7aW1wb3J0Lm1ldGEuZW52Lk1PREV9YCk7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzsifQ==


### System Info

```shell
System:
    OS: Linux 6.8 EndeavourOS
    CPU: (4) x64 AMD Ryzen 7 5800X 8-Core Processor
    Memory: 6.44 GB / 11.65 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 18.20.2 - /usr/bin/node
    Yarn: 1.22.22 - /usr/bin/yarn
    npm: 10.7.0 - /usr/bin/npm
    pnpm: 9.1.2 - /usr/bin/pnpm
  Browsers:
    firefox-developer-edition: 127.0b4
  npmPackages:
    vite: ^5.2.0 => 5.2.12

Used Package Manager

npm

Logs

No response

Validations

hi-ogawa commented 2 months ago

It looks like what's happening is that Vite's transformMiddleware changes response based on Accept: text/html request header (which Browser sets when opening a page directly):

https://github.com/vitejs/vite/blob/dbd6214f6fa5d35647cbd00580c76788ce894e9e/packages/vite/src/node/server/middlewares/transform.ts#L198-L200

but this affects only when there's no vite server module cache, so the behavior looks inconsistent.

https://github.com/vitejs/vite/blob/dbd6214f6fa5d35647cbd00580c76788ce894e9e/packages/vite/src/node/server/transformRequest.ts#L251-L255

When there's no cache, Vite fallbacks to viteServeStaticMiddleware and it responds plain js file content. Another factor is that Vite also has cachedTransformMiddleware which returns early based on etag and if-none-match.

Here is a simpler repro using curl:

$ curl -H 'Accept: text/html' http://localhost:5173/main.js
console.log(`vite mode: ${import.meta.env.MODE}`);

$ curl http://localhost:5173/main.js
import.meta.env = {"BASE_URL": "/", "DEV": true, "MODE": "development", "PROD": false, "SSR": false};console.log(`vite mode: ${import.meta.env.MODE}`);

//# sourceMappingURL=data:application/json;base64,eyJ2Z...

$ curl -H 'Accept: text/html' http://localhost:5173/main.js
import.meta.env = {"BASE_URL": "/", "DEV": true, "MODE": "development", "PROD": false, "SSR": false};console.log(`vite mode: ${import.meta.env.MODE}`);

//# sourceMappingURL=data:application/json;base64,eyJ2Z...