从 TypeScript 中省略"require"和"exports" 发出的 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 简化包装(?

笔记:

  • 我建议的输出完全符合AMD规范。
  • 空的依赖数组是模块具有零依赖关系的唯一方法(与省略依赖关系数组相反,这意味着requireexportsmodule依赖关系(。

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

在实施之前,有什么务实的解决方法的想法吗?(或者,真的有没有办法让TypeScript做到这一点?(

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

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

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

需要

你说:

.. 并且仅在我明确导入它们时才包含要求或导出,即import relativeRequire = require("require");

除非它已经存在,否则您不能使用require。所以它在那里很好。

出口

一旦导出某些内容,就需要exports。如果你想有一个根导出,如export =,那么TypeScript将其映射到return。但是有了export const foo = 123,它就需要使用exports.

它在那里没有任何害处,任何性能影响都非常小。

最新更新