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

时间:2017-06-29 22:45:41

标签: typescript amd

给出以下TypeScript文件,

export = {};

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

define(["require", "exports"], function (require, exports) {
  "use strict";
   return {};
});

但是,我宁愿它发出

define([], function() {
    "use strict";
    return {};
});

...如果我明确导入它们,只包括requireexports,即

import relativeRequire = require("require");

有没有办法告诉TypeScript不要在发出的AMD模块中发出requireexports(即要求它使用CommonJS simplified wrapping)?

注意:

  • 我建议的输出完全符合AMD spec
  • 空依赖项数组是only way,模块具有零依赖性(而不是省略依赖项数组,这意味着requireexports和{{1} } dependencies)。

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

在实施之前,是否有任何实用的解决方法? (或者,实际上是否有某种方法可以使TypeScript执行此操作?)

2 个答案:

答案 0 :(得分:3)

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

我不知道TypeScript会以什么方式开箱即用。我最近研究过TypeScript如何发出define调用,因为我需要将名为"module"的虚拟模块添加到依赖项列表中。 (如果使用Angular,则希望使用module.id将当前模块的id传递给Angular,以便它可以解析相对模板路径等问题。您可以使用module.id而不会出现CommonJS问题默认情况下,依赖列表中不包括输出但是输出module。)我在{{1}发射了它。它使用regexp修改依赖关系列表以添加tsc,并修改回调以添加相应的参数。这对我有用,因为我正在添加。对于您要执行的操作,这不是一个很好的方法,因为您想要删除依赖项,但可能会出现删除它们会导致代码无效的情况。

对于解决方法,您可以使用Esprima检查tsc生成的JavaScript以及模块"module"和{{1}的值传递给tsc的工厂函数中的代码不使用它,然后从依赖项列表中删除未使用的模块,并将参数列表中的相应参数传递给工厂函数。这将是最通用的解决方案。 (除此之外,它与使用AMD加载器在工厂函数中提供的异步"require"调用(形式为"exports")兼容。)但编码此逻辑可能与它将产生一个拉请求,define首先发出你想要的代码。

答案 1 :(得分:1)

需要

你说:

  

..如果我明确导入它们,只包括require或exports,即import relativeRequire = require("require");

除非已存在,否则您无法使用require。它的好处就在那里。

出口

导出内容后,需要

exports。如果您希望在export =中进行根导出,则TypeScript会将其映射到return。但是使用export const foo = 123时,需要使用exports

在那里没有任何伤害,任何对性能的影响都是微乎其微的。

相关问题