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

Using spread operator on a Set inside an Array literal results in unexpected transformed code with plugin-legacy #3076

Closed
mwojtul opened this issue Apr 21, 2021 · 2 comments · Fixed by #3406
Labels
p3-minor-bug An edge case that only affects very specific usage (priority) plugin: legacy

Comments

@mwojtul
Copy link

mwojtul commented Apr 21, 2021

Describe the bug

When running Vite's build process to create a legacy build using plugin-legacy, using the spread operator on a Set inside an Array literal produces different behavior than expected.

For example, [...new Set([1, 1, 2, 3])] will evaluate to [1, 2, 3] in modern browsers. However, the transformed code is [].concat(new Set([1, 1, 2, 3])), which will evaluate to [Set(3)] instead.

In troubleshooting it I narrowed it down to the loose option of babel-preset-env: https://github.com/vitejs/vite/blob/main/packages/plugin-legacy/index.js#L251. Setting it to false results in the code being transformed how I'd expect, but it affects all plugins which probably isn't ideal. I'd be happy to submit a PR, just not entirely sure what the best fix is yet - maybe turning loose off for only proposal-object-rest-spread, if possible?

Reproduction

https://github.com/mwojtul/vite-plugin-legacy-spread-operator-on-set

System Info

  • vite version: 2.1.5
  • Operating System: macOS
  • Node version: 14.16.0
  • Package manager: npm (6.14.11)
@keuby
Copy link

keuby commented May 8, 2021

我也遇到了同样的问题,在使用 @vitejs/plugin-legacy 这个插件打包的时候,他将 vue 的一段代码做了错误的转换,导致 vue 执行报错。

runtime-core/src/scheduler 的第 160 行

activePreFlushCbs = [...new Set(pendingPreFlushCbs)]

编译后的结果为

activePreFlushCbs = [].concat(new Set(pendingPreFlushCbs))

此时在运行到 runtime-core/src/scheduler 的第 176 行时会报错 Uncaught TypeError: activePreFlushCbs[preFlushIndex] is not a function

runtime-core/src/scheduler 的第 188 行

const deduped = [...new Set(pendingPostFlushCbs)]

编译后的结果为

var deduped = [].concat(new Set(pendingPostFlushCbs))

此时在运行到 runtime-core/src/scheduler 的第 215 行时会报错 Uncaught TypeError: activePostFlushCbs[postFlushIndex] is not a function

@mwojtul
Copy link
Author

mwojtul commented May 13, 2021

I think a fix for this could be specifying assumptions:

loadBabel().transform(raw, {
    ...
    assumptions: {
        iterableIsArray: false,
    },
})

The code compiles as expected after that, but the recordAndRemovePolyfillBabelPlugin plugin doesn't catch the import statements from it. A plugin like https://github.com/uiwjs/babel-plugin-transform-remove-imports does though, so updating how recordAndRemovePolyfillBabelPlugin works to use CallExpression and/or ImportDeclaration might be the way to go.

@Shinigami92 Shinigami92 linked a pull request May 14, 2021 that will close this issue
9 tasks
@Shinigami92 Shinigami92 added bug p3-minor-bug An edge case that only affects very specific usage (priority) and removed pending triage labels May 14, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p3-minor-bug An edge case that only affects very specific usage (priority) plugin: legacy
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants