Rollup 构建的 JavaScript 文件无法提供正确的顺序。

huangapple go评论70阅读模式
英文:

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

问题

创建了一个 TypeScript 项目并使用 Rollup 进行构建,但出现了错误:

[1]:https://i.stack.imgur.com/rBA0q.png

![1]

然后我仔细查看构建后的文件,发现 `Text` 类在 `Carobj` 类之前被定义:

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

那么在使用 Rollup 构建项目时,如何让 Carobj 类在 Text 类之前呢?

我希望 Rollup 能够正确顺序构建代码。


<details>
<summary>英文:</summary>

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

[1]:https://i.stack.imgur.com/rBA0q.png

![1]

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

```js
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.

答案1

得分: 1

你在导出CarObj并重新导出Textindex.ts)的模块导入CarObj并导出Texttext.ts)的模块之间存在循环依赖。

当你尝试从index.ts中导入任何内容(就像你的入口点所做的一样),无论是CarObjText还是什么都不是,它首先会加载index.ts,然后加载它的依赖项,包括text.ts,而text.ts又会加载其尚未加载的依赖项。在声明所有变量并设置导入/导出之后,当所有text.ts的依赖项都得到满足时(再次排除index.ts,因为它已经在被导入的过程中),它会被执行,尝试初始化class Text,但由于它尝试扩展的CarObj仍然处于暂时死区中,所以会出现错误。如果它已经完成,index.ts模块可以在满足了所有它的依赖项之后被执行,以此类推,一直回到入口点。

所以这不是Rollup的问题,它只是以与单独模块执行相同的顺序和作用域捆绑代码,这导致了相同的异常。

修复方法很简单:将class CarObj放入单独的模块中,并在text.ts中只导入它,而不是导入text.tsindex.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";
//                     ^^^^^^^ - 不是"../index"!
export class Text extends CarObj {
  
}
英文:

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 &quot;./lib/obj&quot;;
export { Text } from &quot;./lib/text&quot;;
// lib/obj.ts
export class CarObj {
  
}
// lib/text.ts
import { CarObj } from &quot;./obj&quot;;
//                     ^^^^^^^ - not &quot;../index&quot;!
export class Text extends CarObj {
  
}

huangapple
  • 本文由 发表于 2023年2月18日 16:37:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定