将大型Typescript项目转换为ES6模块



我有一个相当大的应用程序(约650个文件),目前它混合实现了ES6模块和遗留全局命名空间内部模块和类。

我想转到100%ES6模块。

迭代方法

要实现这一点,我需要首先添加"export"关键字,将所有全局对象转换为ES6模块。

一旦我添加"export",该全局对象就不再是全局对象,并且使用该对象的每个文件现在都有一个编译器错误"object not found"(即无法读取未定义的属性"xxx")。

要解决此问题,必须在文件中添加一个"导入",从而将其转换为ES6模块,从而"去全局化"该文件中的所有对象,从而在其他文件中导致新的"找不到对象"错误。。

简而言之,这种迭代方法似乎不会很好地工作。

可能的"一举多得"解决方案:

  1. 遍历所有ts文件
    1. 以编程方式将export添加到所有顶级类、模块和变量中
    2. 将这些汇总到一个列表中
  2. 生成一个桶(globalBarrel)文件,重新导出上一步中收集的所有导出
  3. 再次遍历所有ts文件
    1. 对于每个ts文件,将import {list, of, symbols, exported, by, the, barrel,file} from "./globalBarrel"添加到每个文件
  4. 编译干净?
    1. 可能会有一些循环依赖问题需要清理。这样做
  5. 当我们将来编辑每个文件时,使用vsCode"Organize Imports"命令删除许多不需要的文件

正如@jfriend000所说:

获取非模块化代码并尝试以编程方式将其转换为模块化只会造成混乱。

但将所有内容一次性放入模块将使真正的模块化过程更容易。

问题

这是最好的方法吗?有什么建议吗?

要实现这一目标,我需要通过添加"export"关键字将所有全局对象转换为ES6模块。

一旦我添加"export",该全局对象就不再是全局对象,并且使用该对象的每个文件现在都有一个编译器错误"object not found"(即无法读取未定义的属性"xxx")。

要解决此问题,必须在文件中添加一个"导入",从而将其转换为ES6模块,从而"去全局化"该文件中的所有对象,从而在其他文件中导致新的"找不到对象"错误。。

右。避免这种恶性循环的诀窍是,每次将文件转换为模块时,还要将该模块分配给一个全局变量,您可以从其他非模块文件中引用该全局变量,而无需将其转换为模块。这需要一些样板;这个公开的建议会稍微减少样板。

我认为您当前必须使用某种绑定工具来确保加载所有非模块文件并将其贡献到单个全局作用域,以便它们可以访问彼此的定义。首先用以下代码创建一个文件,并配置bundler以确保它首先运行:

namespace Modules {
// Force `Modules` to be created at runtime.
(() => {})();
}

现在,如果你从开始

// a.ts
namespace A {
export const a = 42;
}
// b.ts
namespace B {
console.log(A.a);
}

你可以转换到:

// a.ts
export const a = 42;
import * as A_ from "./a";
declare global {
namespace Modules {
export import A = A_;
}
}
Modules.A = A_;
// b.ts
namespace B {
console.log(Modules.A.a);
}

并且CCD_ 3将能够访问具有完整类型信息的CCD_。

这是最好的方法吗?有什么建议吗?

我怀疑这是一个好方法,当然不是最好的方法。

采用非模块化代码并尝试以编程方式将其转换为模块化代码只会造成混乱。我确信这是可以做到的,但它并没有真正获得任何好处。这只会让事情变得更加混乱。你只需要把一个非模块化的体系结构变成一堆非模块化、高度交叉依赖的模块。您的体系结构将不会得到改进,代码现在将更加复杂,而不是不那么复杂。

更好的方法是逐步重新设计功能领域,使其真正成为"模块化"。为某个功能区域创建一个接口,将其打包到一个模块中,然后转换该功能的所有用户以导入该接口并使用它。这可以一次完成一个功能区域。你不必一下子把整件事都弄碎,然后再把它拼凑起来。

摆脱共享全局需要重新思考设计。仅仅将一堆共享的全局变量打包到一个模块中,让每个人都导入,并不能真正改善设计——事实上,这可能会让情况变得更糟。代码和以前一样相互交织和依赖。

您可以一次增量地对代码的一个功能区域进行模块化重新设计,而不是一下子造成一个巨大的混乱,实际上并不能改善代码的体系结构。

如果我要解决这个问题,我可能会创建一个程序中所有主要功能点的顶级图表,并确保650个文件中的每一个都在图表中的某个地方表示。然后,我开始逐步挑选最容易模块化的部分(那些接口最干净、依赖性最少的部分)。随着越来越多的东西被放入模块,剩下的部分开始变得不那么复杂。如果真的可以访问交织在代码中的全局变量,那么你真的必须重新思考设计的各个部分,要么创建包含数据的对象并传递这些数据,要么将全局数据移动到相关模块中,并为这些数据提供导出的访问器。

最新更新