preactjs / preact-cli

😺 Your next Preact PWA starts in 30 seconds.
MIT License
4.68k stars 376 forks source link

Spreading sets spreads to an array of sets instead of a standard array #1597

Closed ACPixel closed 2 years ago

ACPixel commented 2 years ago

Currently working on a few things and one of the libraries I'm using is tmi.js, within this library is a ...new Set(["abc", "xyz"]) running this code in node or browser spreads the set like an array, however in preact this is not the case and the spread returns a set in an array.

What is the current behaviour? Spreading a set returns a set in an array instead of an array

Steps to Reproduce Anywhere within a Preact application add console.log([ ...new Set(['test', 'test']) ])

What is the expected behaviour? The set should be spread to a standard array containing ["test"]

This seems to be caused by loose: true in the babel config, however I am not certain as I'm not familiar enough with babel to debug this properly

Here is a babel repl link with reproduction, turning the "loose" option on and off makes it output code that either works or does not work as expected. Having read through babel issues on this subject it is defined behavior as loose mode is meant to only work if your code is "the most obvious" as such maybe preact shouldn't be enabling loose mode by default?

https://babeljs.io/repl/#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.6&spec=false&loose=true&code_lz=MYewdgziA2CmB00QHMAUBtABPHZYHdMBlWAFwwHJTYJSKAaTKmugXQEpMOg&debug=false&forceAllTransforms=true&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact&prettier=false&targets=&version=7.15.7&externalPlugins=&assumptions=%7B%7D

Environment Info:
  System:
    OS: Windows 10 10.0.19042
    CPU: (20) x64 Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz
  Binaries:
    Node: 14.15.4 - C:\Program Files\nodejs\node.EXE       
    Yarn: 1.22.10 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.10 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1023.0), Chromium (94.0.992.38)
  npmPackages:
    preact: ^10.3.2 => 10.5.14
    preact-cli: ^3.0.0 => 3.2.2
    preact-render-to-string: ^5.1.4 => 5.1.19
    preact-router: ^3.2.1 => 3.2.1
rschristian commented 2 years ago

This has already been fixed with #1580, just not published yet.

You can create a preact.config.js file, or add to your existing, with the following in the meantime:

function findBabelPlugin(arr, pluginName) {
    return arr.find((plugin) =>
        (typeof plugin === 'string' && plugin.includes(pluginName)) ||
        (typeof plugin[0] === 'string' && plugin[0].includes(pluginName))
    )
}

export default { 
    webpack(config, env, helpers) {
        if (env.dev) {
            const { rule } = helpers.getLoadersByName(config, 'babel-loader')[0];
            const babelConfig = rule.options;

            findBabelPlugin(babelConfig.presets, 'preset-env')[1].loose = false;
            findBabelPlugin(babelConfig.plugins, 'class-properties')[1].loose = false;
        }
    }
};

This will disable loose mode.

ACPixel commented 2 years ago

Thank you! Closing this issue :)

rschristian commented 2 years ago

Hey, just wanted to let you know Preact-CLI v3.3.0 was published, which should alleviate the need for a custom config. Should be handled for you now.