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

and*_*win 29 javascript import wildcard ecmascript-6 es6-modules

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

import * as Foo from './foo';

VS:

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

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

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

Airbnb风格指南中,他们建议不要使用通配符,因此总会有默认的导入对象,而这一点.

Tam*_*dus 22

如果你使用webpack和新的uglify提供的死代码消除,或者使用树形抖动的rollupjs,那么将删除未使用的导入.

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

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

  • 我在哪里可以阅读更多相关信息?例如官方文档或 github 问题线程。 (3认同)
  • 如果我 `import * as Foo from './foo'`,并且我只使用 `Foo.bar`,那么 `Foo.bar2` 和 `Foo.bar3` 会被作为死代码消除吗? (2认同)
  • @bsapaka 是的,如果根本不使用 `Foo.bar2` 和 `Foo.bar3`。 (2认同)

idm*_*adj 18

关于这部分问题:

即使我没有在主代码中使用它们,第一个实际上会导入所有内容吗?

以下是使用Babel 6.26编译的方法:

命名

import { bar, bar2, bar3 } from './foo';
Run Code Online (Sandbox Code Playgroud)

......变得......

'use strict';

var _foo = require('./foo');
Run Code Online (Sandbox Code Playgroud)

通配符

import * as Foo from './foo';
Run Code Online (Sandbox Code Playgroud)

......变得......

'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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

值得一提的是编译的代码将只包含一个单一的_interopRequireWildcard定义,一个呼叫require_interopRequireWildcard为每个进口.

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


小智 10

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


Moe*_*sra 6

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

但是如果您需要使用特定的函数或const,则最好避免使用“ import *”,并明确说明需要执行的操作。