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

Omit "require" and "exports" from TypeScript emitted AMD dependencies

给定以下 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)?

备注:


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

在实施之前有什么实用的解决方法吗? (或者,实际上有什么方法可以让 TypeScript 做到这一点吗?)

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

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

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

需要

你说:

.. and only include require or exports if I explicitly import them, i.e. import relativeRequire = require("require");

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

出口

exports 是你导出东西的时候需要的。如果你想在 export = 中进行根导出,则 TypeScript 将其映射到 return。但是对于 export const foo = 123,它需要使用 exports

它的存在没有任何害处,对性能的影响确实很小。