Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESM Modules: ssrTransform blindly overwrites variable named as an import instead of checking for a locally scoped variable with the same name when destructuring an array #5472

Closed
7 tasks done
jbmolle opened this issue Oct 29, 2021 · 0 comments

Comments

@jbmolle
Copy link
Contributor

jbmolle commented Oct 29, 2021

Describe the bug

This bug is similar to nuxt/nuxt#13736.
Found it by using i18n with nuxt3.
Here is the description from kazupon nuxt/nuxt#12585
If we destructure an array like let [ a, b, c ] = [ 1, 2, 3] and we do an import { a } from 'my-package' then vite doesn't see the local scope and replace the variable name.

Reproduction

Doing the test in packages/vite/src/node/ssr/tests/ssrTransform.spec.ts line 178
Actual test works:

test('do not rewrite when variable is in scope', async () => {
  const result = await ssrTransform(
    `import { fn } from 'vue';function A(){ const fn = () => {}; return { fn }; }`,
    null,
    null
  )
  expect(result.code).toMatchInlineSnapshot(`
    "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\");
    function A(){ const fn = () => {}; return { fn }; }"
  `)
  expect(result.deps).toEqual(['vue'])
})

Changing test with object destructuring also works:

test('do not rewrite when variable is in scope', async () => {
   const result = await ssrTransform(
     `import { fn } from 'vue';function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }`,
     null,
     null
   )
   expect(result.code).toMatchInlineSnapshot(`
     "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\");
     function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }"
   `)
   expect(result.deps).toEqual(['vue'])
 })

But using test with array destructuring does not work:

test('do not rewrite when variable is in scope', async () => {
   const result = await ssrTransform(
     `import { fn } from 'vue';function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }`,
     null,
     null
   )
   expect(result.code).toMatchInlineSnapshot(`
     "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\");
     function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }"
   `)
   expect(result.deps).toEqual(['vue'])
 })

The last test fails and we get: function A(){ let [fn, test] = ['foo', 'bar']; return { fn: vite_ssr_import_0.fn }; }

System Info

System:
    OS: Linux 5.4 Ubuntu 20.04.3 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz
    Memory: 6.04 GB / 15.32 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.13.0 - /usr/bin/node
    Yarn: 1.22.17 - /usr/bin/yarn
    npm: 8.1.0 - /usr/bin/npm
  Browsers:
    Chrome: 87.0.4280.88
    Chromium: 95.0.4638.54
    Firefox: 93.0
  npmPackages:
    vite: workspace:* => 2.7.0-beta.0

Used Package Manager

pnpm

Logs

No response

Validations

@Niputi Niputi closed this as completed Nov 19, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Dec 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants