我需要TypeScript编译器发出的所有.js
文件都包括对define
函数的AMD样式的调用。看来这应该是TypeScript可以做的一件事,但是我不知道如何一直使用它。
现在,只要.ts文件具有依赖项(import
/ require
)或产生依赖项(export
),发出的Javascript将包含AMD define调用。但是,对于我的项目,有效的脚本文件可能既不具有依赖项也不产生依赖关系。
缺少的define
调用是一个问题,因为我使用了--outFile
编译器开关来生成一个包含所有AMD模块的单个javascript文件,并且该文件/模块立即执行,而无需等待与该级别的其他AMD模块一样,可能在require
语句中使用。
示例如下:
module_a.ts 愚蠢,但说明性的破坏性内容(如果意外运行)
const el = document.getElementById("app");
el.innerHTML = "";
在与TypeScript 2.9.2兼容时,使用以下开关:tsc --target es5 --module amd --outFile application.js module_a.ts
会产生以下结果:
application.js
var el = document.getElementById("app");
el.innerHTML = "";
但是,此版本的 module_a.ts 将呈现我要查找的内容:
module_a.ts
export const el = document.getElementById("app");
el.innerHTML = "";
application.js 无论我是否使用import
/ require
/ export
define("module_a", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.el = document.getElementById("app");
exports.el.innerHTML = "";
});
如果找不到强制编译器发出定义的方法,那么我会回来(有一个新问题)找出我的下一个任务,以编写TSLint规则来检测这种情况,以便我知道我需要在TS模块中添加伪造的export
。
答案 0 :(得分:0)
The documentation说,在顶层拥有import
或export
是编译器确定文件是模块还是全局脚本的一部分的唯一方法:
在TypeScript中,就像在ECMAScript 2015中一样,任何包含 顶级导入或导出被视为模块。相反,一个文件 没有任何顶级进出口声明的情况将被视为 脚本的内容在全局范围内可用(因此 以及模块)。
正如您在问题中提到的,define
仅在编译文件是模块时才出现在输出中。
因此,添加伪造的顶级export
或import
是唯一的解决方案。做到这一点的方法在运行时没有任何影响(实际上没有从AMD模块导入或导出任何内容)是导入在其他模块中定义的某种类型:
import {SomeType} from './some-module';
如果在运行时从未使用过SomeType
,则编译器将不会在JavaScript中发出import
或require
,但仍会将文件编译为模块并添加define
功能。
如果您的target
和module
选项为ESNext
,则有一种更新且可以说是更好的方法来获得相同的结果-只需在某处添加此语句即可将文件转换为模块:
import.meta;
我认为没有tslint规则要求每个文件都必须是一个模块。我不知道要实现这样的规则有多难-如果tslint规则可以轻松访问TypeScript AST,那么如果它是一个模块,则该规则可以检查SourceFile
的{{3}}:
/**
* The first "most obvious" node that makes a file an external module.
* This is intended to be the first top-level import/export,
* but could be arbitrarily nested (e.g. `import.meta`).
*/
/* @internal */ externalModuleIndicator: Node;