"Troubiling with preact-cli and Babel/TypeScript configurations for enabling correct functionality of Symbol.iterator and spread syntax

Within my codebase, there exists a function named range that is responsible for generating ranges. The implementation of this function is outlined below:

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

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

            while (n <= max) yield n++
        }
    }
}

When utilizing Array.from(range(1, 5)), the expected output of [1, 2, 3, 4, 5] is achieved. However, when attempting to spread the range with [...range(1, 5)], an unexpected result of [{[Symbol.iterator]: ƒ}] is returned, indicating a single-element array containing the range object.

Further investigation reveals that the spread operator is being transpiled into the following construct:

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

While this approach would be suitable for spreading arrays, it fails when other types of iterables are involved.

The configuration within my .tsconfig file is consistent with previous setups, targeting ESNext. Modifying the downlevelIteration setting to either true or false has no impact, leading me to believe the issue lies elsewhere.

It appears that Babel may be the culprit here, but I am struggling to determine the correct configuration adjustments. As my primary concern revolves around compatibility with modern versions of Chromium and Firefox, legacy browser support is not a critical factor.

Samples from package.json:

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

Contents of .babelrc:

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

The configuration in my preact.config.js closely mirrors the one found here: preact.config.js permalink. Here is the relevant excerpt:

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,
            }
        }
        // ...    
    })
    // ...
}

What steps should be taken to rectify this issue?

Answer №1

To ensure everyone benefits from it, I am reiterating the solution shared by @PeterLehnhardt in the comments: Firstly, you need to create a preact.config.js file.

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

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

Answer №2

After much troubleshooting, the solution was to completely eliminate the usage of babel-loader. I made a modification in preact.config.js by replacing the relevant section with the following:

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

Although this resolved the issue for me, I am still interested in alternative methods that do not involve removing Babel altogether.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to loading a different domain page with JavaScript

Looking to enhance a page on my site (let's say it's on domain A) by pulling in additional content from another page, located on domain B. However, browsers typically block this functionality for security purposes. After researching, I've c ...

AngularJS - Unchecked radio button issue

Within my code, there is an ng-repeat including several radio buttons: <div class="panel panel-default" ng-repeat="item in vm.itemList"> ... <td ng-show="item.edit"> <div class="row"> ...

What could be causing the variable in my Angular application, written in typescript, not to update within a function?

I'm encountering a peculiar issue. Within my CategoryComponent component, I have a variable in scope as follows: @Input() category: CategoryModel; Whenever I perform a simple post request using a service and receive data back, I modify this variabl ...

Pausing until the user clicks the button again

I have implemented two buttons on this page - one with a class of 'arrow-up' and the other with a class of 'arrow-down'. Clicking on the 'arrow-down' button will smoothly scroll down to the next section, while clicking on the ...

Tips on saving content that changes automatically

I am curious about the best way to store dynamically displayed HTML content. For example, when a certain element is clicked on a website, I want text to appear elsewhere on the page. One idea I had was to create a variable in a JavaScript/jQuery script to ...

Troubleshoot the issue of the service function not being triggered

Seeking help with my Angular project as I am facing an issue with resolve and $resource. Despite spending a whole day on it, I couldn't find a solution. When using resolve to fetch data with $resource and ui-router, the service method never gets calle ...

Issues with React Native imports not functioning properly following recent upgrade

Hey there, I’ve been tasked with updating an old React-Native iOS project from version 0.25.1 to 0.48.0. However, I’m encountering several compiler issues and struggling to navigate through the code updates. The project includes an index.ios.js file s ...

Storing the information filled out in the form and utilizing it to navigate to the correct destination URL

With the generous assistance and insightful advice from members of Stack Overflow, I am nearing completion of my quiz project. However, I do have a few lingering questions regarding some final touches needed for the project. Before delving into those quest ...

Are we retrieving multiple APIs the right way?

Looking for some guidance on fetching two APIs in React. I have created two functions to handle this task and called them simultaneously within another function. Should I stick with this approach or move the API calls to componentDidMount? Additionally, I& ...

Obtain the IDs of the previous and next list items if they exist?

Hey there friends, I've hit a roadblock and could really use your help. I'm trying to figure out how to get the previous and next list items in a specific scenario. Let's say I have a ul with three li elements, and the second one is currentl ...

Ways to validate the presence of the second tr element in a table using jQuery

<table id="jobSkills"> <tr><th></th><th></th></tr> <tr><td></td></tr> //checking if this tr is present or not.? </table> I have a table with the task of determining whether the second ...

Conceal a div once the content in a separate div has finished loading

After loading an image in slices inside a div, I want to ensure that the entire content is loaded before displaying the div. To achieve this, I am using another div as a mask while the content loads: <div id="prepage" style="position:absolute; left:0px ...

Exploring the world of child routing in Angular 17

I've been experimenting with child routing in Angular and encountered some confusion. Can someone explain the difference between the following two routing configurations? {path:'products',component:ProductsComponent,children:[{path:'de ...

What is the term used to describe the reflective language feature and is there a commonly accepted method to implement it?

Imagine you have an object and you're looking to retrieve a string representing the name of the property you're accessing. Does that particular operation have a designated term? It seems like a form of reflection, but is there a more precise term ...

Combining subclasses in TypeScript

Do you need help with a tricky situation? ...

Express JS error: Invalid Parameters Detected

My Express JS application has the following route: app.get('/fetchnotes/:id', function(req, res) { var id = req.params.id; console.log(id); connection.query('SELECT * from dn_notes where id=?',[id], function(err, rows, fiel ...

Listening for key combinations in VueJS using a mounted event listener

I am facing an issue with my global key listener - it only catches single key strokes. How can I modify it to capture combinations like ctrl+enter? mounted() { window.addEventListener ( "keypress", e => { console.log ...

Is all of the app fetched by Next.js when the initial request is sent?

After doing some research online, I learned that Next.js utilizes client-side routing. This means that when you make the first request, all pages are fetched from the server. Subsequent requests will render those pages in the browser without needing to com ...

Organize based on 2 factors, with emphasis on 1

Looking for a way to sort a list of posts by two variables - date (created) and score (score>). The main goal is to prioritize the sorting based on the score, so that the highest scoring posts appear first.</p> <p>To clarify, the desired so ...

Fetching information from a data object using asyncData in Nuxt

Is there a method to retrieve object properties as keys from the asyncData() function? data() { return { bookmark_btn: { status: null, loading: false } } } I attempted to access data object properties in the following ...