何时使用 "import * as Foo" 与 "import Foo"?

When to use "import * as Foo" versus "import Foo"?

我正在将 BackboneJS (v1.2.2) 项目转换为带有 BabelJS 的 ES6。

我注意到两者之间存在差异:

import Backbone from 'backbone'

import * as Backbone from 'backbone'

阅读 here 后,我了解到前者正在导入 Backbone 的默认导出,而后者允许我 "import the whole module and refer to its named exports via property notation."

我很难理解它们之间的区别。两个实例都返回对象,但前者似乎用额外的 properties/methods 装饰。至少我会假设导入 "the whole module" 会有更多 properties/methods... 但我看到的恰恰相反。

一个模块可以导出单个 "default export" 和/或一个或多个命名导出。

使用问题中的第一个语法导入只会导入默认导出,并为该对象设置命名标识符(Backbone 在您的示例中)。

第二种语法称为命名空间导入,它将整个模块导入单个 "namespace" 对象下。

例如:

export.js

let b = {b: 2};
export default {a: 1}; // <- this is the ONLY default export
export {b};
export let c = {c: 3};

import.js

import SomeName from 'export'; // 'SomeName' is now the {a: 1} instance.
import {b} from 'export'; // 'b' is now the {b: 2} instance.
import * as ns from 'export'; /* 'ns' now has properties 'default', 'b' & 'c',
  representing {a: 1}, {b: 2} & {c: 3} respectively */

这取决于模块的接口以及您希望如何使用它。在 Backbone 的 npm 包的情况下,并没有真正的默认导出,所以当由 Babel 转译时,两个版本应该大致相同。

At the very least I would presume importing "the whole module" would have more properties/methods

这取决于默认导出是什么以及有哪些命名导出。这里有一个例子,说明情况并非如此:

exporter.js

export default {
  one: "One",
  two: "Two",
  three: "Three",
};

export var a;

importer.js

// Has 3 props ['one', 'two', 'three']
import defaultExport from 'exporter';

// Has 2 props ['default', 'a'].
import * as allExports from 'exporter';