51

与通天塔反应。我对导入和 module.exports 感到困惑。我假设在将 ES6 代码转换为 ES5 时,babel 会将导入和导出分别转换为 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");

我使用带有预设 es2015 的 babel 来转编译它。这给了我以下错误

未捕获的 TypeError: (0 , _animals.Tiger) 不是函数

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

我在这里想念什么?

编辑: 我使用 browserify 作为模块捆绑器。

4

3 回答 3

58

export { Tiger }将等同于module.exports.Tiger = Tiger

反之,module.exports = Tiger将等价于export default Tiger

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

于 2016-01-14T16:52:35.573 回答
37

如果您想导入:

module.exports = Tiger

您可以使用以下结构:

import * as Tiger from './animals'

然后它将起作用。

另一种选择是按照@Matt Molnar 的描述更改导出,但只有当您是导入代码的作者时才有可能。

于 2018-05-09T20:31:30.403 回答
12

未设置时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';
于 2020-10-27T11:59:45.587 回答