通配符或星号 (*) 与命名或选择性导入 es6 javascript

Wildcard or asterisk (*) vs named or selective import es6 javascript

只是想知道哪个是使用导入的最佳方式:

import * as Foo from './foo';

对比:

import { bar, bar2, bar3 } from './foo';

在效率方面,例如,我使用 webpack 来捆绑所有 JavaScript 文件。即使我没有在主代码中使用它们,第一个实际上会导入所有内容吗?

我能找到的一些参考文献是:

Airbnb style guide, they are recommending no wildcard so there will always be default import object, and this.

如果您使用带有新 uglify 提供的死代码消除的 webpack,或带有 tree-shaking 的 rollupjs,那么未使用的导入将被删除。

我部分同意 airbnb 风格指南不使用通配符导入,尽管 javascripts 通配符导入不会遭受与例如 pythons 或 javas 通配符导入相同的疾病,即它不会污染定义变量名的范围在其他模块中(您只能通过 moduleB.foo 访问它们,而在使用 import * as moduleB from ... 时不能通过 foo 访问它们)。

关于测试的文章:我有点理解这些担忧,但我没有看到那里无法解决的问题。您可以使用一些自定义模块加载器模拟导入本身(自定义 amd 模块加载器实际上是 15 行代码),因此您不必弄乱测试模块的本地范围。

我同意@Tamas。
如果您需要对目标文件中所有导出的完全访问权限,那么您可以使用 import * as Foo from './foo'; 要么 import foo from './foo':

但是如果您需要使用特定的函数或常量,那么最好避免使用 "import *" 并明确说明您需要做什么。

关于这部分问题:

Will the first one actually importing everything even though I'm not using them in the main code?

下面是它是如何用 Babel 6.26 编译的:

已命名

import { bar, bar2, bar3 } from './foo';

...变成...

'use strict';

var _foo = require('./foo');

通配符

import * as Foo from './foo';

...变成...

'use strict';

var _foo = require('./foo');

var Foo = _interopRequireWildcard(_foo);

function _interopRequireWildcard(obj) { 
    if (obj && obj.__esModule) { 
        return obj;
    } else {
        var newObj = {}; 
        if (obj != null) { 
            for (var key in obj) { 
                if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
            }
        }
        newObj.default = obj; 
        return newObj;
    }
}

在这两种情况下,整个文件都是通过 require 导入的。

使用通配符导入,定义了一个 _interopRequireWildcard 函数,用于将所有导出分配给命名空间变量。

值得注意的是,编译后的代码将只包含一个 _interopRequireWildcard 定义,并且每次导入都会调用一次 require_interopRequireWildcard

最终,使用通配符导入将在 运行 时涉及更多处理,并导致编译后的 js 的大小略有增加。

因为,使用现代 WebPack 设置,两者将生成相同的 compiled/transpiled JS,命名导入的真正价值在于它的表现力。通过命名您的导入,您是在告诉任何打开文件的人,您将使用模块中的哪些功能。这可能有用的一个例子是在编写测​​试时,如果需要模拟,你有一个明确的导入列表来模拟。