我想在一个文件中导入一个类:
"use strict";
import models from "../model";
class Foo {
bar() {
}
}
export default new Foo();
当我使用import时,它可以工作,例如:
import Foo from "./foo";
console.log(Foo.bar); // [Function bar]
问题是,使用require执行此操作会给我一些未定义的内容:
var Foo = require("./foo");
console.log(Foo.bar); // undefined
并且Foo变量似乎是一个空类。为什么会这样?发生了什么事?
答案 0 :(得分:9)
这是因为import
导入与require
不同。导入语法为import X from "Y"
的模块时,会自动导入默认导出,因为语法是按规范导入默认导出。但是,当您require
时,默认导出不会自动导入,就像您期望的那样。您必须添加.default
才能获得require
的默认导出,例如:require("./foo").default
。
看看Babel transpiles一些示例代码:
export { x }
变为:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.x = x;
这是有道理的,因为x
只是正常导出。然后你会继续做:
require("module").x;
接收x
。同样,请尝试以下方法:
export default new Foo();
那变为:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = new Foo();
您将看到默认导出作为名为exports
的属性附加到default
对象,就像导出x
属性x
一样。这意味着,要使用require
获取默认导出,您需要执行以下操作:
require("module").default;
现在解释它undefined
的原因。在该行:
var Foo = require("./foo");
Foo
这里实际上只是一个default
属性的对象:
{
default: //Whatever was exported as default
}
因此,尝试执行Foo.bar
会产生undefined
,因为没有bar
属性。您需要访问default
属性才能访问您的实例。
你可能认为这有点笨拙,而其他人也这么做。这就是there's a plugin摆脱额外.default
的必要性的原因。该插件会module.exports = exports["default"]
将module.exports
从ES5分配到exports["default"]
。 1
import
和require
对于import
语法,Babel执行以下转换:
import Foo from "./foo";
Foo.bar();
变为:
"use strict";
var _foo = require("./foo");
var _foo2 = _interopRequireDefault(_foo);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_foo2.default.bar();
要逐行分解,Babel只需require
个模块。然后,它在模块上调用_interopRequireDefault
。使用obj && obj.__esModule
进行检查以确保模块实际导出任何内容,并使用ES2015 / ES6语法导出模块。如果是,则按原样返回模块,否则返回{ default: obj }
。这是为了确保ES5中的module.exports = x
与ES2015 / ES6中的export default x
相同。您会注意到,对于默认导入语法,Babel会自动添加.default
以检索默认导出。
但是,相应的代码包含require
:
var Foo = require("./foo");
Foo.bar();
是完全有效的ES5代码,因此没有任何内容被编译。因此,.default
在使用时永远不会添加到Foo
。因此,不会检索默认导出。
1 应该注意module.exports
和exports
只是引用同一个对象,请参阅this answer。 module.exports
保存从模块导出的数据。 module.exports = x
成功导出x
作为默认值并且不需要.default
上的额外require
的原因是因为您要将module.exports
分配给一个module.exports
单身的东西。由于require("module")
包含导入的数据,module.exports
会导入x
,module.exports
。require("module")
。如果module.exports
为3,则{ blah: "foo" }
为3.如果require("module")
是{ blah: "foo" }
之类的对象,则module
将为module.exports
。默认情况下,exports.default
和module.exports
是对象。
另一方面,default
使用保存默认导出的exports = x
属性导出对象(指向与x
相同的对象)。您可能希望exports
导出module.exports
作为默认值,但由于exports
被分配了对module.exports
的引用,这将打破引用,div
将不再指向[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable<Season> seasons { get; set; }
。