RequireJS 模块的 TypeScript 编译生成行 Object.defineProperty(exports, "__esModule", value: true )

Posted

技术标签:

【中文标题】RequireJS 模块的 TypeScript 编译生成行 Object.defineProperty(exports, "__esModule", value: true );如何摆脱它?【英文标题】:TypeScript compilation of RequireJS module generates line Object.defineProperty(exports, "__esModule", value: true ); How to get rid of it?RequireJS 模块的 TypeScript 编译生成行 Object.defineProperty(exports, "__esModule", value: true );如何摆脱它? 【发布时间】:2018-04-28 02:37:05 【问题描述】:

这就是我的 tsconfig.json 文件的样子:


    "compileOnSave": true,
    "compilerOptions": 
        "module": "amd",
        "noImplicitAny": false,
        "removeComments": false,
        "preserveConstEnums": true,
        "strictNullChecks": true,
        "sourceMap": false
    

我有一个名为 a.ts 的打字稿文件,它是一个 AMD 模块(我正在使用 requirejs),它看起来像:

export function a() 
    var a = 
        b: 5
    ;
    return a;

编译后的 javascript 文件如下所示:

 define(["require", "exports"], function (require, exports) 
    "use strict";
    Object.defineProperty(exports, "__esModule",  value: true );
    function a() 
        var a = 
            b: 5
        ;
        return a;
    
    exports.a = a;
 );

我需要生成的 JavaScript 文件是:

define(function () 
    "use strict";
    var a = 
        b: 5
    ;
    return a;
);

所以我需要 a) 移除 Object.defineProperty(exports, "__esModule", value: true );线路 b) 从define中移除require和exports依赖 c) 没有内部函数“a”,然后在导出时公开“a”,而是简单地在 a.js 文件中返回“a”对象

我需要对 tsconfig.json 和 a.ts 文件进行哪些更改才能获得所需的 Javascript 文件或更接近它的文件,从当前 a.js 到我需要的任何改进都会很棒,即使是 1 或 2满足 3 个要求。

一种方法是使a.ts完全像我想要的a.js文件然后编译,但是由于另一个不相关的要求,我必须使用export语句的方式来制作amd模块。感谢您阅读到这里。请帮忙。

【问题讨论】:

Typescript AMD Target Resolving to CommonJS的可能重复 @AluanHaddad 是的,这似乎是重复的。所以这意味着没有办法?如果不阻止我对导出对象的功能,则必须有某种方法来删除 Object.defineProperty 行并要求和导出依赖项,a) 和 b) 在我上面的问题中? 【参考方案1】:

您的导出问题可以通过使用export = 语法轻松解决。如果你用这个来编码你的模块:

var a = 
  b: 5
;

export = a;

转译成这样:

define(["require", "exports"], function (require, exports) 
    "use strict";
    var a = 
        b: 5
    ;
    return a;
);

请注意,您还会丢失 __esModule 属性的创建过程。

您的问题的其余部分与another question 重复。简而言之,TypeScript 编译器没有提供避免发出 requireexports 依赖项的选项。如果你想删除它们,你必须自己处理发出的代码。

【讨论】:

谢谢。那解决了它。当我运行 amdclean 时,需要和导出依赖项被删除。我是打字稿的新手,所以请多多包涵。这解决了模块返回 Object 文字的情况。当我的模块返回一个函数时,你能给我一些见解或一些代码 sn-p,那么我要导出什么?我很困惑,因为我之前使用了定义,例如定义([ ],function() var func = function() ; return func;);还有依赖关系呢?我可以写 import('myDep');直接在模块上方,这样编译后的文件仍然满足我原来的条件 a) 和 b) ? 如果你想返回一个函数,你可以做export = function myFunction() /* ... */ export = ... 语法意味着“我希望右侧的内容成为模块的值”。在 AMD 中,这转换为 return ...。在 CommonJS 中,它将是 module.exports = ...。您可以通过这种方式导出任何内容:对象、函数、原语等。关于import,您的import 语句不会单独导致tsc 添加回__esModule 属性或使无法删除 requireexports 依赖项。 我对您使用amdclean 感到困惑。 (我假设您在谈论this 工具)。我没有使用过它,但从我阅读的内容来看,它会将 AMD 代码转换为非 AMD 代码。如果您的最终结果不是 AMD,那么为什么首先要有 tsc 输出 AMD 模块?您可以输出 CommonJS 模块并避免 __esModule 的整个问题和不希望的依赖项。 是的,AMD-clean 确实做到了这一点,但它在删除 AMD 组件后生成纯 JS 代码,并且没有任何 module.exports 等语句,因此它也不会生成 NodeJS 代码。请解释一个更基本的等级。使用 RequireJS 的主要目的是使代码模块化,并递归加载模块的依赖项及其依赖项的依赖项等。我不需要将最终程序作为 npm 模块提供给任何人,我正在浏览器上运行生成的 JS 模块。我认为 browserify 会为节点模块做到这一点,但我认为那也太 RequireJS 和 AMD 模块在某些情况下非常有用。但是,我不会使用 AMD 除非我需要在运行时加载其身份未知的模块直到运行时。否则,我只会将所有内容都输出为 CommonJS 模块并使用 Webpack 生成最终的包。此外,当需要添加贡献者或从外部获得帮助时,与知道 amdclean 的人相比,您更有机会找到了解 Webpack 的人。我就是一个例子:我编写了复杂的 Webpack 配置并且可以帮助解决 Webpack 问题,但我从未使用过 amdclean

以上是关于RequireJS 模块的 TypeScript 编译生成行 Object.defineProperty(exports, "__esModule", value: true )的主要内容,如果未能解决你的问题,请参考以下文章

typescript+reactjs+requirejs:如何将 react-dom 导入 typescript

Requirejs多次加载相同的Javascript文件

Gulp + Webpack ts loader 移除 requirejs 和定义模块名称注解

TypeScript 包管理

如何使用 jQuery、RequireJS 和 KnockoutJS 创建基本的 TypeScript 项目

TypeScript:编译删除未引用的导入