From 29da61ccd4a1e7ff5edf9864791881604682f1bf Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Mon, 22 Aug 2022 23:28:32 -0500 Subject: [PATCH 01/40] fix(define): don't modify string literals fix #9790 --- packages/vite/src/node/plugins/define.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index 0448327d660ed6..5b51bfd6d5dc28 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -1,4 +1,5 @@ import MagicString from 'magic-string' +import { stripLiteral } from 'strip-literal' import type { ResolvedConfig } from '../config' import type { Plugin } from '../plugin' import { transformStableResult } from '../utils' @@ -134,6 +135,7 @@ export function definePlugin(config: ResolvedConfig): Plugin { let hasReplaced = false let match: RegExpExecArray | null + code = stripLiteral(code) while ((match = pattern.exec(code))) { hasReplaced = true const start = match.index From 0781d42652a5ec514c24a1bfca7a68ab65e2048f Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Mon, 22 Aug 2022 23:30:08 -0500 Subject: [PATCH 02/40] test(define): verify define ignores literals --- .../src/node/__tests__/plugins/define.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/vite/src/node/__tests__/plugins/define.spec.ts b/packages/vite/src/node/__tests__/plugins/define.spec.ts index 932560a749f24d..bc640877ece6e8 100644 --- a/packages/vite/src/node/__tests__/plugins/define.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/define.spec.ts @@ -37,4 +37,22 @@ describe('definePlugin', () => { 'const isSSR = false;' ) }) + + test('ignores import\0.meta.env inside strings', async () => { + const transform = await createDefinePluginTransform({ + 'import\0.meta.env': '{}' + }) + const inputs = [ + `const isFoo = "import\0.meta.env.FOO";`, + `const isFoo = 'import\0.meta.env.FOO';`, + 'const isFoo = `import\0.meta.env.FOO`;', + `const isFoo = \` +"import.meta.env.FOO" +\`;` + ] + for (const input of inputs) { + // transform() returns null when no replacement is made + expect(await transform(input)).toBe(null) + } + }) }) From cf93c33b35143a2b324cf619419d13d7b8c46493 Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Mon, 22 Aug 2022 23:55:28 -0500 Subject: [PATCH 03/40] test(define): expand tests out of loop to easily identify failures --- .../src/node/__tests__/plugins/define.spec.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/vite/src/node/__tests__/plugins/define.spec.ts b/packages/vite/src/node/__tests__/plugins/define.spec.ts index bc640877ece6e8..60ec949d9cdd5e 100644 --- a/packages/vite/src/node/__tests__/plugins/define.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/define.spec.ts @@ -42,17 +42,14 @@ describe('definePlugin', () => { const transform = await createDefinePluginTransform({ 'import\0.meta.env': '{}' }) - const inputs = [ - `const isFoo = "import\0.meta.env.FOO";`, - `const isFoo = 'import\0.meta.env.FOO';`, - 'const isFoo = `import\0.meta.env.FOO`;', - `const isFoo = \` -"import.meta.env.FOO" -\`;` - ] - for (const input of inputs) { - // transform() returns null when no replacement is made - expect(await transform(input)).toBe(null) - } + // transform() returns null when no replacement is made + expect(await transform(`const isFoo = "import\0.meta.env.FOO";`)).toBe(null) + expect(await transform(`const isFoo = 'import\0.meta.env.FOO';`)).toBe(null) + expect(await transform('const isFoo = `import\0.meta.env.FOO`;')).toBe(null) + expect( + await transform(`const isFoo = \` + "import\0.meta.env.FOO" + \`;`) + ).toBe(null) }) }) From ed16db29c0bf8a258a6fd888ad2765d77b4ce6f4 Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Mon, 22 Aug 2022 23:59:45 -0500 Subject: [PATCH 04/40] test(define): verify define ignores nested string of all quote types --- .../vite/src/node/__tests__/plugins/define.spec.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/vite/src/node/__tests__/plugins/define.spec.ts b/packages/vite/src/node/__tests__/plugins/define.spec.ts index 60ec949d9cdd5e..02ef83ece33268 100644 --- a/packages/vite/src/node/__tests__/plugins/define.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/define.spec.ts @@ -51,5 +51,15 @@ describe('definePlugin', () => { "import\0.meta.env.FOO" \`;`) ).toBe(null) + expect( + await transform(`const isFoo = \` + 'import\0.meta.env.FOO' + \`;`) + ).toBe(null) + expect( + await transform(`const isFoo = \` + \`import\0.meta.env.FOO\` + \`;`) + ).toBe(null) }) }) From 589d30b7f2d1434d8c5dc2128497121ac5b7ba52 Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Tue, 23 Aug 2022 01:05:27 -0500 Subject: [PATCH 05/40] fix(define): don't modify string literals in ssr --- packages/vite/src/node/plugins/define.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index 5b51bfd6d5dc28..2ff76e0f839e0b 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -124,13 +124,6 @@ export function definePlugin(config: ResolvedConfig): Plugin { return null } - if (ssr && !isBuild) { - // ssr + dev, simple replace - return code.replace(pattern, (_, match) => { - return '' + replacements[match] - }) - } - const s = new MagicString(code) let hasReplaced = false let match: RegExpExecArray | null From 603073c21e9d9e6c9944807d1dbbbeb3cf596b83 Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Tue, 23 Aug 2022 01:06:16 -0500 Subject: [PATCH 06/40] test(define): verify define ignores literals in ssr mode --- .../src/node/__tests__/plugins/define.spec.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/plugins/define.spec.ts b/packages/vite/src/node/__tests__/plugins/define.spec.ts index 02ef83ece33268..8f180d329964ac 100644 --- a/packages/vite/src/node/__tests__/plugins/define.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/define.spec.ts @@ -38,7 +38,7 @@ describe('definePlugin', () => { ) }) - test('ignores import\0.meta.env inside strings', async () => { + test('ignores import\0.meta.env inside strings for non-SSR', async () => { const transform = await createDefinePluginTransform({ 'import\0.meta.env': '{}' }) @@ -62,4 +62,33 @@ describe('definePlugin', () => { \`;`) ).toBe(null) }) + + test('ignores import\0.meta.env inside strings for SSR', async () => { + const transform = await createDefinePluginTransform( + { + 'import\0.meta.env': '{}' + }, + true, + true + ) + // transform() returns null when no replacement is made + expect(await transform(`const isFoo = "import\0.meta.env.FOO";`)).toBe(null) + expect(await transform(`const isFoo = 'import\0.meta.env.FOO';`)).toBe(null) + expect(await transform('const isFoo = `import\0.meta.env.FOO`;')).toBe(null) + expect( + await transform(`const isFoo = \` + "import\0.meta.env.FOO" + \`;`) + ).toBe(null) + expect( + await transform(`const isFoo = \` + 'import\0.meta.env.FOO' + \`;`) + ).toBe(null) + expect( + await transform(`const isFoo = \` + \`import\0.meta.env.FOO\` + \`;`) + ).toBe(null) + }) }) From 2eb1aea1f67d6cc44abdf00b6cad3d8f2e6f934b Mon Sep 17 00:00:00 2001 From: Tony Trinh Date: Tue, 23 Aug 2022 15:43:09 -0500 Subject: [PATCH 07/40] test(define): include tests from #9621 --- playground/react/App.jsx | 2 ++ playground/react/__tests__/react.spec.ts | 7 +++++++ playground/react/components/DefineVariable.tsx | 3 +++ playground/vue/DefineVariable.vue | 3 +++ playground/vue/Main.vue | 2 ++ playground/vue/__tests__/vue.spec.ts | 9 +++++++++ 6 files changed, 26 insertions(+) create mode 100644 playground/react/components/DefineVariable.tsx create mode 100644 playground/vue/DefineVariable.vue diff --git a/playground/react/App.jsx b/playground/react/App.jsx index 3ec29ba38d893b..531ee7e959f114 100644 --- a/playground/react/App.jsx +++ b/playground/react/App.jsx @@ -1,5 +1,6 @@ import { useState } from 'react' import Dummy from './components/Dummy?qs-should-not-break-plugin-react' +import DefineVariable from './components/DefineVariable' import Button from 'jsx-entry' function App() { @@ -27,6 +28,7 @@ function App() { + ) diff --git a/playground/react/__tests__/react.spec.ts b/playground/react/__tests__/react.spec.ts index 15f6319220d7f2..1b3700dd0bdcfb 100644 --- a/playground/react/__tests__/react.spec.ts +++ b/playground/react/__tests__/react.spec.ts @@ -37,3 +37,10 @@ test.runIf(isServe)( ]) } ) + +test('defined/reserved words are preserved in string literals', async () => { + expect(await page.textContent('.define-variable')).toBe( + // FIXME: insert \0 to prevent Vite from replacing import.meta.env + 'import\0.meta.env'.replace('\0', '') + ) +}) diff --git a/playground/react/components/DefineVariable.tsx b/playground/react/components/DefineVariable.tsx new file mode 100644 index 00000000000000..465baf04d0adbb --- /dev/null +++ b/playground/react/components/DefineVariable.tsx @@ -0,0 +1,3 @@ +export default function DefineVariable() { + return
import.meta.env
+} diff --git a/playground/vue/DefineVariable.vue b/playground/vue/DefineVariable.vue new file mode 100644 index 00000000000000..aa57b934362bc5 --- /dev/null +++ b/playground/vue/DefineVariable.vue @@ -0,0 +1,3 @@ + diff --git a/playground/vue/Main.vue b/playground/vue/Main.vue index c5f3d27402fda7..6e7cc2017875a4 100644 --- a/playground/vue/Main.vue +++ b/playground/vue/Main.vue @@ -22,6 +22,7 @@ +