从TypeScript发出的AMD依赖项中省略"require"和"exports"

Roy*_*ker 6 amd typescript

给定以下TypeScript文件,

export = {};
Run Code Online (Sandbox Code Playgroud)

tsc(带"module": "amd")会发出:

define(["require", "exports"], function (require, exports) {
  "use strict";
   return {};
});
Run Code Online (Sandbox Code Playgroud)

但是,我宁愿它发出

define([], function() {
    "use strict";
    return {};
});
Run Code Online (Sandbox Code Playgroud)

......并且只包括require或者exports我明确地导入它们,即

import relativeRequire = require("require");
Run Code Online (Sandbox Code Playgroud)

有没有办法告诉TypeScript不要发射requireexports发射AMD模块(即要求它不要使用CommonJS简化包装)?

笔记:

  • 我建议的输出完全符合AMD规范.
  • 一个空的依赖关系数组是唯一的方法用于模块到具有零间的依赖关系(相对于省略依赖性阵列,这意味着require,exportsmodule依赖关系).

更新2017年7月4日:看起来这实际上是TypeScript GitHub仓库中的一个开放问题:https://github.com/Microsoft/TypeScript/issues/669

在实施之前,是否有任何实用的解决方法?(或者,有没有办法让TypeScript这样做?)

Lou*_*uis 3

我认为你正在尝试做的事情没有实质性的优势。对于任何不仅仅是玩具应用程序的应用程序来说,通过删除未使用的依赖项节省的执行时间与应用程序其余部分的执行时间相比都显得相形见绌。和require都是exports虚拟模块,实例化成本非常低。(我所说的“虚拟”是指它们完全位于您使用的 AMD 加载程序内部,不需要从网络或磁盘上的文件进行任何获取。)我看到您提到的问题 669自 2014 年 9 月以来一直处于开放状态,并被视为“已接受”自 2015 年 4 月以来。似乎没有人受到如此严重的伤害,以至于急于提出拉取请求。

我不知道 TypeScript 有什么方法可以开箱即用地做你想做的事情。我最近研究了 TypeScript 如何发出其define调用,因为我需要将名为的虚拟模块添加"module"到依赖项列表中。(如果您使用 Angular,则需要将module.id当前模块的 id 传递给 Angular,以便它可以解析相对模板路径等内容。您可以module.id毫无问题地使用 CommonJS 输出,但module默认情况下不包含AMD 输出在依赖项列表中。)我通过编写一个构建步骤来解决这个问题,该步骤tsc在发出代码后修改发出的代码tsc。它使用正则表达式来修改依赖项列表以添加"module",并修改回调以添加相应的参数。这对我有用,因为我正在添加。对于您想要执行的操作来说,这不是一个足够好的方法,因为您想要删除依赖项,但在某些情况下删除它们可能会导致无效代码。

作为解决方法,您可以使用Esprima检查生成的 JavaScript ,如果传递给工厂函数内的代码未使用tsc模块的值"require"和值,则从依赖项列表中删除未使用的模块,并从传递给工厂函数的参数列表。这将是最通用的解决方案。(除此之外,它与使用AMD 加载器在工厂函数内提供的异步调用(形式)兼容。)但是编码此逻辑可能与生成已发出的拉取请求一样复杂。首先你想要的代码。"exports"definerequirerequire([...], function (...) {})tsc