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

Posted

技术标签:

【中文标题】preact-cli/babel/typescript - 让 Symbol.iterator 和 [...spread] 正常工作【英文标题】:preact-cli/babel/typescript - getting Symbol.iterator and [...spread] to work correctly 【发布时间】:2021-01-25 14:08:28 【问题描述】:

在我的代码中,我有一个名为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, 2, 3, 4, 5],正如预期的那样。

在进一步调试后,扩展运算符似乎被转译为:

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

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

.tsconfig 与我之前使用的相同,针对ESNext,并将downlevelIteration 更改为truefalse 没有任何作用,所以我相当有信心问题不存在.

看起来这与 Babel 有关,但我不知道如何正确配置它。旧版浏览器支持不是什么大问题 - 如果它适用于最新的 Chromium 和 Firefox,我很高兴。

package.json:

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

.babelrc:

 "presets": [ [ "preact-cli/babel",  "modules": "commonjs"  ] ] 

preact.config.js 与此处的相同:preact.config.js permalink。以下是相关部分:

webpack(config, env, helpers, options) 
    // ...

    config.module.rules = config.module.rules.map(rule => 
        if (rule.loader === 'babel-loader') 
            const use = [
                
                    loader: 'babel-loader',
                    options: rule.options
                ,
                
                    loader: 'ts-loader'
                
            ]

            return 
                ...rule,
                loader: undefined,
                options: undefined,
                use,
            
        
        // ...    
    )
    // ...

我将如何解决这个问题?

【问题讨论】:

"downlevelIteration": true 似乎解决了我这边的问题:codesandbox.io/s/async-bush-ns3y7?file=/src/index.ts @PeterLehnhardt 该应用使用 Parcel,而不是 Webpack、Babel 和 Preact。问题肯定出在构建工具上,而不是代码上。 @是的,你是对的。我稍微抬头一看,发现this。你试过了吗? 【参考方案1】:

最终通过完全删除babel-loader 解决了这个问题。我用这个替换了preact.config.js的相关部分:

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

不过,我仍然很想知道如何在不完全移除 Babel 的情况下解决此问题

【讨论】:

@PeterLehnhardt 在他的评论中指出了必要的配置。这不是真正的答案,而是不必要的解决方法。 我的问题是“我该如何解决这个问题”,自我回答,因为它解决了我的问题并完美地适合我的用例(仅限现代浏览器)。我不认为这是一种解决方法,因为我一开始就不需要 Babel。我也在@PeterLehnhard 的第二条评论之前发布了这个(这可能是一个更好的通用解决方案,即使不是针对我的具体情况)。【参考方案2】:

我将在 cmets 中重复 @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, 
    
  

【讨论】:

以上是关于preact-cli/babel/typescript - 让 Symbol.iterator 和 [...spread] 正常工作的主要内容,如果未能解决你的问题,请参考以下文章