Search code examples
javascripttypescriptrollup

The js file builded by Rollup can't give the right order


I create a typescript project and use Rollup to build it, but error:

1

and then I find this bug in the builded file carefully, and discover the class Text has defined before class Carobj

var newcar = (function (exports){
  // ......
  class Text extends Carobj {
    // ......
  }
  
  class Carobj {
    // ......
  }
})({})

So how to make class Carobj in front of Text when use Rollup to build project?

I wanna Rollup can use right order to build codes.


Solution

  • You have a circular dependency between the module exporting CarObj and re-export Text (index.ts) and the module importing CarObj and exporting Text (text.ts).

    When you attempt to import anything from index.ts (like your entrypoint does) - it doesn't matter whether that's CarObj or Text or nothing - then it will first load index.ts, then load its dependencies, including text.ts, which in turn loads its dependencies that were not already loaded. After all variables are declared and imports/exports are set up, when all of text.ts' dependencies are met - again excluding index.ts which is already in the process of being imported - it is executed, attempting to initialise the class Text, and runs into an error because the CarObj it attempts to extend is still in the temporal dead zone. If it had finished, the index.ts module could have been executed after all its dependencies were met, and so on, back until the entry point.

    So this is not a problem of rollup, it just bundles the code in the same order, with the same scopes, as it would have been executed with individual modules. Which leads to the same exception.

    The fix is simple: put the class CarObj into a separate module, and import only that in text.ts, not the index.ts that imports text.ts.

    // index.ts
    export { CarObj } from "./lib/obj";
    export { Text } from "./lib/text";
    
    // lib/obj.ts
    export class CarObj {
      …
    }
    
    // lib/text.ts
    import { CarObj } from "./obj";
    //                     ^^^^^^^ - not "../index"!
    export class Text extends CarObj {
      …
    }