Node.js TypeScript外部节点模块有时会传输到module.exports和exports

Node.js TypeScript外部节点模块有时会传输到module.exports和exports,node.js,typescript,commonjs,Node.js,Typescript,Commonjs,我正在将我的节点应用程序转换为使用TypeScript外部模块。运行应用程序时一切正常,但在转换一些my.ts文件时,mocha测试“爆炸”,原因是SyntaxError:Unexpected reserved word 经过多次调试,我发现了以下可重复出现的故障案例。我有一个简单的autoRoles.ts文件,它定义了可用的用户角色。在使用外部模块之前,它看起来像: /// <reference path="../../typings/backend_typings.d.ts" />

我正在将我的节点应用程序转换为使用TypeScript外部模块。运行应用程序时一切正常,但在转换一些my.ts文件时,mocha测试“爆炸”,原因是
SyntaxError:Unexpected reserved word

经过多次调试,我发现了以下可重复出现的故障案例。我有一个简单的autoRoles.ts文件,它定义了可用的用户角色。在使用外部模块之前,它看起来像:

/// <reference path="../../typings/backend_typings.d.ts" />

module.exports.roles = {
  // role definitions
}
//
module.exports.roles={
//角色定义
}
现在在转换之后:

/// <reference path="../../typings/backend_typings.d.ts" />

export let roles = {
  // role definitions
}
//
导出let角色={
//角色定义
}
运行mocha测试时,会生成以下错误:

>> Mocha exploded!
>> SyntaxError: Unexpected reserved word
>>     at exports.runInThisContext (vm.js:53:16)
>>     at Module._compile (module.js:413:25)
>>     at Object.Module._extensions..js (module.js:452:10)
>>     at Module.load (module.js:355:32)
>>     at Function.Module._load (module.js:310:12)
>>     at Module.require (module.js:365:17)
>>     at require (module.js:384:17)
>>     at Object.<anonymous> (/Users/abc/esupport/code/asp_v4/lib/models/userRole.ts:77:17)
>>     at Module._compile (module.js:434:26)
>>     at Object.Module._extensions..js (module.js:452:10)
>>     at Module.load (module.js:355:32)
>>     at Function.Module._load (module.js:310:12)
>>     at Module.require (module.js:365:17)
>>     at require (module.js:384:17)
>>     at Object.<anonymous> (/Users/abc/esupport/code/asp_v4/lib/users/lib/ssoAuth.ts:7:17)
>>     at Module._compile (module.js:434:26)
>>     at Object.Module._extensions..js (module.js:452:10)
>>     at Module.load (module.js:355:32)
>>     at Function.Module._load (module.js:310:12)
>>     at Module.require (module.js:365:17)
>>     at require (module.js:384:17)
>>     at Object.<anonymous> (/Users/abc/esupport/code/asp_v4/lib/users/index.ts:5:31)
摩卡咖啡爆炸了! >>SyntaxError:意外的保留字 >>在exports.runInThisContext(vm.js:53:16) >>在模块处编译(Module.js:413:25) >>在Object.Module.\u extensions..js(Module.js:452:10) >>在Module.load(Module.js:355:32) >>在Function.Module.\u加载(Module.js:310:12) >>at Module.require(Module.js:365:17) >>根据需要(module.js:384:17) >>反对。(/Users/abc/esupport/code/asp_v4/lib/models/userRole.ts:77:17) >>在模块处编译(Module.js:434:26) >>在Object.Module.\u extensions..js(Module.js:452:10) >>在Module.load(Module.js:355:32) >>在Function.Module.\u加载(Module.js:310:12) >>at Module.require(Module.js:365:17) >>根据需要(module.js:384:17) >>反对。(/Users/abc/esupport/code/asp_v4/lib/Users/lib/ssoAuth.ts:7:17) >>在模块处编译(Module.js:434:26) >>在Object.Module.\u extensions..js(Module.js:452:10) >>在Module.load(Module.js:355:32) >>在Function.Module.\u加载(Module.js:310:12) >>at Module.require(Module.js:365:17) >>根据需要(module.js:384:17) >>反对。(/Users/abc/esupport/code/asp_v4/lib/Users/index.ts:5:31) 我可以在autoRoles.ts文件的旧实现和新实现之间切换,分别让mocha通过和失败。注意,userRoles.ts的第77行有一个
require('/autoRoles')

在比较传输版本时,唯一的区别是旧版本使用“module.exports”,而新版本仅使用“exports”

旧的:

//
exports.roles={
//角色定义
}
新的:

//
module.exports.roles={
//角色定义
}
所以我知道“导出”只是“module.exports”的一个快捷方式,所以我无法解释为什么这会导致摩卡失败,但我知道如果我在两者之间切换,而不做任何其他改变,摩卡就会“爆炸”。我还注意到,对于其他传输模块,tsc有时使用“module.exports”,有时使用“exports”。为什么会有不同,更重要的是,为什么摩卡咖啡会爆炸

意外保留字

“严格使用”位于文件顶部。您可能有一个保留关键字的变量。看见如果文件中有该头,TypeScript将对此类变量名发出警告

module.exports.roles={
不是错误的来源

我还注意到,对于其他传输模块,tsc有时使用“module.exports”,有时使用“exports”

它与nodejs约定类似,基本上是保存运行时需要解析的字符(字节)

export let foo = 123;
我会给你

exports.foo = 123;
(因为您已经知道,
exports==module.export
因此,
exports.foo==module.export.foo
。)但是:

let foo = 123;
export = foo;
是的

var foo = 123;
module.exports = foo;

因为如果您重新分配导出,即
exports=foo
,那么
module.export!==exports
。因此您可以使用
exports
进行扩展…但不分配。

经过更多的调试后,我发现mocha没有使用tsc传输的生成的.js源代码文件。我不确定具体如何使用,但它正在尝试执行位于.ts文件中的“export var roles”,而“export”是一个保留字

我偶然发现了这一点,它告诉我摩卡正在尝试自己的转储。那个家伙建议使用“打字需要”,但是那个包看起来像是在被弃用“TS节点”的中间。所以我改变了我的格式化TS配置,看起来像:

mochaTest: {
    test: {
        options: {
            reporter: 'spec',
            require: [
                'ts-node/register'
            ]
        },
        src: ['lib/test/**/*.spec.js']
    }
},
这是可行的,但我非常高兴有人能告诉我mocha在做什么。还有,为什么mocha在使用export的其他.ts文件中成功地传输/没有检测到“保留字”

编辑2015年10月30日:


所以我发现了为什么mocha试图执行我的.ts文件。我愚蠢地将其中一些文件作为require('/path/file.ts')导入,我应该在那里关闭'.ts'扩展名。我的mocha runner中不再需要'ts node'。这也解释了为什么mocha只在我的一些.ts文件上出错。

感谢您对我的建议和解释“module.exports”vs“exports”。不幸的是,“use strict”并不能解决问题。请参阅我的答案,了解我如何修复它。
var foo = 123;
module.exports = foo;
mochaTest: {
    test: {
        options: {
            reporter: 'spec',
            require: [
                'ts-node/register'
            ]
        },
        src: ['lib/test/**/*.spec.js']
    }
},