我对打字稿很新,我正在为WebGl编写一个小型原型框架。我目前正在重构我的项目,并且在如何组织我的项目时遇到了一些问题,因为(模块和命名空间)方法似乎都有严重的缺点。
这篇文章不是关于如何使用这些模式,而是如何克服这些模式带来的问题。
来自C#这似乎是最自然的方式。每个类/模块都获得它适当的命名空间,并在tsconfig.json中提供“outFile”参数,因此所有内容都连接成一个大文件。 编译后,我将根命名空间作为全局对象。依赖项没有内置到项目中,所以你手动必须在你的html中提供所需的* .js文件(不好)
示例文件
namespace Cross.Eye {
export class SpriteFont {
//code omitted
}
}
示例用法(通过在html中提供js文件,您必须确保将Cross命名空间加载到全局命名空间中)
namespace Examples {
export class _01_BasicQuad {
context: Cross.Eye.Context;
shader: Cross.Eye.ShaderProgram;
//code omitted
}
}
对于大多数项目,我们建议使用外部模块并使用命名空间进行快速演示并移植旧的JavaScript代码。
来自https://basarat.gitbooks.io/typescript/content/docs/project/namespaces.html
Typescript支持ES6模块,它们是新的和有光泽的,每个人似乎都认为它们是可行的方式。这个想法似乎是每个文件都是一个模块,通过在import语句中提供文件,你可以非常明确地定义你的依赖关系,这使得捆绑工具很容易有效地打包你的代码。我大多数每个文件有一个类似乎与dhte模块模式不兼容。
这是重构后的文件结构:
此外,我在每个文件夹中都有一个index.ts文件,因此我可以通过import * as FolderModule from "./folder"
导入所有类
export * from "./AggregateLoader";
export * from "./ImageLoader";
export * from "./TiledLoader";
export * from "./XhrLoaders";
export * from "./XmlSpriteFontLoader";
示例文件 - 我认为问题在这里变得清晰可见..
import {SpriteFont} from "./SpriteFont";
import {ISpriteTextGlyph, ISpriteChar} from "./Interfaces";
import {Event,EventArgs} from "../../Core";
import {Attribute, AttributeConfiguration} from "../Attributes";
import {DataType} from "../GlEnums";
import {VertexStore} from "../VertexStore";
import {IRectangle} from "../Geometry";
import {vec3} from "gl-matrix";
export class SpriteText {
// code omitted
}
示例用法。如您所见,我不再需要遍历命名空间,因为我可以直接导入类。
import {
Context,
Shader,
ShaderProgram,
Attribute,
AttributeConfiguration,
VertexStore,
ShaderType,
VertexBuffer,
PrimitiveType
} from "../cross/src/Eye";
import {
Assets,
TextLoader
} from "../cross/src/Load";
export class _01_BasicQuad {
context: Context;
shader: ShaderProgram;
// code omitted.
}
在一个完美的世界中,我会使用命名空间模式编写我的框架并将其导出为一个模块,然后可以将其导入并与其依赖项捆绑在一起。然而,如果没有一些丑陋的黑客攻击,这似乎是不可能的。
所以这是我的问题:你是如何处理这些问题的?如何最大限度地减少每种方法所暗示的缺点?
在获得更多关于打字稿和javascript开发的经验之后,我必须指出模块可能是90%所有用例的方法。
最后10%的希望是使用全局命名空间的遗留项目,你想用一些小打字稿(顺便说一下,这样做很好)。
我对模块的大部分评论都可以通过更好的IDE支持来解决。 Visual Studio Code自此添加了自动模块分辨率,效果很好。
答案 0 :(得分:10)
tl;博士:不要选择过去。选择未来:模块。
在ES6模块规范的早期草案中,有一个内联模块概念,然后是has been eliminated in September 2013。但是,2012年,TypeScript团队已经实现了这一概念,该语言的第一个测试版本是:内部模块。然后,没有内联模块的ES6模块has been released in July 2014的最终规范。一年后,2015年7月,使用TypeScript版本1.5,内部模块 has been renamed到名称空间,以避免与标准混淆。
命名空间是一项传统功能。它不会是ECMAScript语言的一部分。 TypeScript团队将继续遵循该标准。自2014年7月发布ECMAScript模块标准以来,TS名称空间没有任何改进。
缺点[ES6模块]
- 如果每个类都是不同的文件,则非常繁琐,您必须反复键入相同的导入语句。
- 重命名文件会破坏您的代码(错误)。
- 重构类名称不会传播到您的导入(非常糟糕 - 可能取决于您的IDE,我使用的是vs-code)
我们希望未来的IDE能够对这些问题进行一些改进。第一个已经被WebStorm解决了。