【问题标题】:What recommendations exist for structuring TypeScript code bases?对于构建 TypeScript 代码库有哪些建议?
【发布时间】:2012-12-05 00:42:43
【问题描述】:

多年来我一直在使用 C#,并且主要习惯于按类型处理单个文件的方式。我也喜欢将文件放入子文件夹(对应于 C# 中的命名空间)。

但是现在我正在使用 TypeScript 构建一个移动 Web 应用程序,并且发现自己以几乎相同的方式构建我的代码。但是,这不太好用:

  • 每个文件都会生成一个模块包装器,因此,如果您有许多具有相同模块的文件,则输出(捆绑时)会包含很多不必要的代码行。
  • 在其他模块中引用类型...不如在 C# 中好,因为您必须在类型名称前加上模块名称。

第一点应该可以通过编写一个小工具从捆绑输出中去除不必要的模块包装器来解决。而且我认为我需要避免使用子模块,而只需将所有内容都放在一个模块中,而不管文件系统位置如何。

有没有比我目前正在做/计划的更好的方法来构建 TypeScript 代码,或者是否推荐使用上述方法?对于喜欢单一职责原则的人来说,有哪些值得考虑的替代方案?

PS:我希望这符合 SO 的指导方针,尽管可能有点主观和开放。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这是我的建议。

    网站

    如果您在网站上使用 TypeScript,请使用模块来封装完整且独立的功能块并将其保存在一个文件中(除非它变得无法管理)。对于“模块 a”对“模块 b”内部位的访问量要保守。

    将所有生成的 JavaScript 打包并压缩到一个文件中。

    声明你的模块:

    module MyModule {
        // ...
    }
    

    并使用参考使它们可用于其他代码文件:

    ///<reference path="MyModule.ts" />
    

    网络应用

    对于网络应用程序,您需要决定脚本繁重的内容将是多少。如果事情要轻量级,请将其视为网站。如果您要编写大量脚本,那么 AMD 就是您的好朋友。

    借助 AMD,您可以使用文件夹结构来组织您的代码。你的文件就是你的模块,所以不要使用module MyModule 声明,而是将你的文件命名为MyModule.ts。然后,您可以使用文件夹和文件结构组织代码,并根据需要导入模块:

    import myModule = module("./Messaging/Async/MyModule");
    

    因此,请将 import 视为您的 using 语句 - 除非您需要为其命名。

    在运行时,您需要一些东西来为您加载模块。 RequireJS 是一个受欢迎的选择。

    您只需在页面中添加一个脚本标签,它会加载 RequiresJS 并告诉它您的顶级模块的名称:

    <script data-main="/Messaging/Async/MyModule" src="scripts/require.js"></script>
    

    服务器应用

    对于服务器应用程序,您几乎肯定会想要使用 CommonJS(例如,nodejs 默认支持)。

    它的工作方式与 AMD 非常相似(AMD 实际上基于 CommonJS),只是服务器会为您加载模块,因此您不需要包含模块加载脚本。

    金子弹

    这真的都是指导。如果您愿意,您可以对非常大的程序使用网站样式捆绑 - 鉴于脚本将被下载一次并被缓存,您可能会认为前期成本值得简单。

    因此,请使用该指南,直到您认为它不适合您的特定计划并希望以不同的方式做事。指导原则是...

    1. 减少对网站的 http 请求数
    2. 提高 Web 应用/服务器应用的可读性和可维护性
    3. 仅加载 Web 应用程序/服务器应用程序所需的内容

    【讨论】:

    • 您仍然可以在 AMD 中使用 module MyModule 声明。只需导出它。
    • 很好的建议,谢谢!我可以在将在客户端设备上运行并从该设备加载其所有 JS 的移动 Web 应用程序中使用 AMD/CommonJS 吗?还是应该为这种情况选择 RequireJS?也就是说,现在我将所有内容捆绑到一个输出文件中,因此我更关心的是写入/设计时的体验,而不是运行时的工作方式,尽管这两个问题显然是交织在一起的。
    • 如果要部署在移动设备上,我可能会选择将其全部捆绑到一个文件中。在那种情况下,没有必要为模块加载而烦恼。
    【解决方案2】:

    这是相当主观的,但值得我们或多或少地使用模块作为命名空间,因此将相关的类组合在一个文件中,除了在我们的视图模型中,我们或多或少坚持一个文件 = 一个类,就像我们对 C# 所做的那样。

    其中一个原因是,在客户端开发中,我们发现自己创建了许多非常小的类和接口(通常每个只有两个或三个参数),通常针对特定组件或视图的工作进行分组,并且将这些整理到一个文件中似乎更有意义。

    【讨论】:

    • 我还开始将一些类型集中在一起,特别是与文件中的类相关的类型定义(接口)。实用主义获胜,但到目前为止,我对单类单文件还可以:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    相关资源
    最近更新 更多