preact-cli / babel / typescript-使Symbol.iterator和[... spread]正常工作

问题描述

在我的代码中,我有一个名为range函数,它可以产生范围。实现如下:

export const range = (min: number,max: number) => {
    // ...

    return {
        // ...
        *[Symbol.iterator]() {
            let n = min

            while (n <= max) yield n++
        }
    }
}
如您所料,

Array.from(range(1,5))给出[1,2,3,4,5]。但是,[...range(1,5)]给出[{[Symbol.iterator]: ƒ}](长度1的数组,包含范围对象),这显然是不正确的。如果我将range附加到window对象上并从浏览器控制台调用它,则[...range(1,5)]将给出[1,5],如预期的那样。

在进一步调试后,似乎已将传播运算符转译为此:

// console.log(() => [...range(1,5)])
ƒ () { return [].concat(range(1,5)) }

如果正在传播的是数组,则可以正常工作,但对于其他类型的可迭代对象则失败。

.tsconfig与我以前使用的相同,将ESNext定位为downlevelIterationtrue并没有任何作用,所以我我非常有信心问题不会出现。

这似乎与Babel有关,但是我不知道如何正确配置它。旧版浏览器支持不是很多问题-如果它在最新的Chromium和Firefox上运行,我会很高兴。

false

package.json

"browserslist": "last 3 chrome versions,last 3 firefox versions"

.babelrc

{ "presets": [ [ "preact-cli/babel",{ "modules": "commonjs" } ] ] } 与此处的preact.config.js permalink相同。这是相关的部分:

preact.config.js

我将如何解决这个问题?

解决方法

我只会在评论中重复@PeterLehnhardt 提供的解决方案,以便每个人都可以看到: 创建 preact.config.js

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

    babelConfig.assumptions = {
      iterableIsArray: false,}
  }
}
,

最后,只需完全删除babel-loader即可解决此问题。我将preact.config.js的相关部分替换为:

if (rule.loader === 'babel-loader') {
    return { loader: 'ts-loader' }
}

我仍然很想知道如何解决此问题的答案,而无需完全删除Babel。