Module.exports 和 ES6 Import

65

使用babel处理React。我对imports和module.exports存在困惑。我假设在将ES6代码转换为ES5时,Babel会将imports和exports分别转换为require和module.exports。

如果我从一个模块导出一个函数并在另一个模块中导入该函数,则代码可以正常执行。但是,如果我使用module.exports导出函数并使用"import"导入它,则会在运行时抛出错误,指出它不是函数。

我编写了一个示例。

// Tiger.js
function Tiger() {
    function roar(terrian){
        console.log('Hey i am in ' +  terrian + ' and i am roaing');
    };
    return roar;
}

module.exports = Tiger;

// animal.js
import { Tiger } from './animals';

var animal = Tiger();
animal("jungle");

我使用了babel和预设es2015来进行转译。这给了我以下错误:

Uncaught TypeError: (0 , _animals.Tiger) is not a function

但是,如果我删除 module.exports = Tiger; 并用 export { Tiger }; 替换它,它就可以正常工作。

我错过了什么??

编辑:我正在使用browserify作为模块打包程序。


你看过 Babel 的输出吗?查看 Tiger.js 转译后的源代码将立即告诉你为什么它不起作用。长话短说:坚持使用一个模块系统或使用像 webpack 这样的模块打包工具来处理不一致性。 - GJK
抱歉提一下,我正在使用browserify作为模块打包工具。 - Nani
3个回答

74

export { Tiger } 相当于 module.exports.Tiger = Tiger

反之,module.exports = Tiger 相当于 export default Tiger

因此,当你使用 module.exports = Tiger,然后尝试使用 import { Tiger } from './animals' 时,实际上是在请求 Tiger.Tiger


1
那么在这里正确的导入语句是什么呢?只需要写成 import Tiger from './animals' 吗? - Michael S
1
我认为是这样,假设您不想改变tiger.js文件。 - Matt Molnar

50

如果您想要导入:

module.exports = Tiger

您可以使用以下结构:

import * as Tiger from './animals'

那么它将会有效。

另一个选项是根据 @Matt Molnar 的描述更改导出方式,但只有在您是所导入代码的作者的情况下才可能实现。


5
import * as Tiger from './animals' 对我有用!谢谢。” - Dessauges Antoine
2
Tiger是上面例子中的一个函数。您不能使用 import * as something 导入可调用对象(函数或类),因为 something 将表示一个 namespace 对象,这是不可调用的。在这种情况下正确的导入方式是默认导入:import Tiger from './animals'; - Slava Fomin II

23

module.exports没有设置时,它指向一个空对象({})。 当您执行module.exports = Tiger时,您告诉运行时从该模块导出的对象是Tiger对象(而不是默认的{}),在这种情况下是一个函数。
由于您想要导入相同的函数,因此导入方式是使用默认导入(import tiger from './tiger')。 否则,如果您想要使用命名导入(import {tiger} from './tiger'),您必须更改module.exports对象或者使用export关键字代替module.exports对象。

默认导入/导出:

// tiger.js
module.exports = tiger;
// or
export default function tiger() { ... }

// animal.js
import tiger from './tiger';

命名导入/导出:

// tiger.js
module.exports = { tiger };
// or
module.exports.tiger = tiger
// or
export const tiger = () => { ... }
// or
export function tiger() => { ... }

// animal.js
import { tiger } from './tiger';

3
请提供更多的上下文信息,以便我能够更好地理解您的要求。 - Supun Praneeth
是的,我的错。我的回答只是为了补充已经解释过的一些解决方案。 - Daniel Rodrigues
良好且不言自明的例子。非常感谢您让理解变得容易。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接