-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(plugin-legacy): prevent global process.env.NODE_ENV mutation (#9741)
- Loading branch information
Showing
5 changed files
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
17 changes: 17 additions & 0 deletions
17
playground/legacy/__tests__/client-and-ssr/client-legacy-ssr-sequential-builds.spec.ts
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { describe, expect, test } from 'vitest' | ||
import { port } from './serve' | ||
import { isBuild, page } from '~utils' | ||
|
||
const url = `http://localhost:${port}` | ||
|
||
describe.runIf(isBuild)('client-legacy-ssr-sequential-builds', () => { | ||
test('should work', async () => { | ||
await page.goto(url) | ||
expect(await page.textContent('#app')).toMatch('Hello') | ||
}) | ||
|
||
test('import.meta.env.MODE', async () => { | ||
// SSR build is always modern | ||
expect(await page.textContent('#mode')).toMatch('test') | ||
}) | ||
}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// this is automatically detected by playground/vitestSetup.ts and will replace | ||
// the default e2e test serve behavior | ||
import path from 'node:path' | ||
import { ports, rootDir } from '~utils' | ||
|
||
export const port = ports['legacy/client-and-ssr'] | ||
|
||
export async function serve(): Promise<{ close(): Promise<void> }> { | ||
const { build } = await import('vite') | ||
|
||
// In a CLI app it is possible that you may run `build` several times one after another | ||
// For example, you may want to override an option specifically for the SSR build | ||
// And you may have a CLI app built for that purpose to make a more concise API | ||
// An unexpected behaviour is for the plugin-legacy to override the process.env.NODE_ENV value | ||
// And any build after the first client build that called plugin-legacy will misbehave and | ||
// build with process.env.NODE_ENV=production, rather than your CLI's env: NODE_ENV=myWhateverEnv my-cli-app build | ||
// The issue is with plugin-legacy's index.ts file not explicitly passing mode: process.env.NODE_ENV to vite's build function | ||
// This causes vite to call resolveConfig with defaultMode = 'production' and mutate process.env.NODE_ENV to 'production' | ||
|
||
await build({ | ||
mode: process.env.NODE_ENV, | ||
root: rootDir, | ||
logLevel: 'silent', | ||
build: { | ||
target: 'esnext', | ||
outDir: 'dist/client' | ||
} | ||
}) | ||
|
||
await build({ | ||
mode: process.env.NODE_ENV, | ||
root: rootDir, | ||
logLevel: 'silent', | ||
build: { | ||
target: 'esnext', | ||
ssr: 'entry-server-sequential.js', | ||
outDir: 'dist/server' | ||
} | ||
}) | ||
|
||
const { default: express } = await import('express') | ||
const app = express() | ||
|
||
app.use('/', async (_req, res) => { | ||
const { render } = await import( | ||
path.resolve(rootDir, './dist/server/entry-server-sequential.mjs') | ||
) | ||
const html = await render() | ||
res.status(200).set({ 'Content-Type': 'text/html' }).end(html) | ||
}) | ||
|
||
return new Promise((resolve, reject) => { | ||
try { | ||
const server = app.listen(port, () => { | ||
resolve({ | ||
// for test teardown | ||
async close() { | ||
await new Promise((resolve) => { | ||
server.close(resolve) | ||
}) | ||
} | ||
}) | ||
}) | ||
} catch (e) { | ||
reject(e) | ||
} | ||
}) | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// This counts as 'server-side' rendering, yes? | ||
export async function render() { | ||
return /* html */ ` | ||
<div id="app">Hello</div> | ||
<div id="mode">${import.meta.env.MODE}</div> | ||
` | ||
} |
This file contains 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