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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42051588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:51:45  来源:igfitidea点击:

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

javascriptimportecmascript-6wildcardes6-modules

提问by andiwin

Just wondering which one is the best way to use import:

只是想知道哪一种是使用 import 的最佳方式:

import * as Foo from './foo';

import * as Foo from './foo';

VS:

对比:

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

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

In terms of efficiency, say for example, I'm using webpack for bundling all the JavaScript files. Will the first one actually importing everything even though I'm not using them in the main code?

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

Some references that I can find are:

我可以找到的一些参考资料是:

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

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

采纳答案by Tamas Hegedus

If you use webpack with the dead code elimination provided by the new uglify, or rollupjs with tree-shaking, then the unused imports will be stripped.

如果你使用 webpack 和新的 uglify 提供的死代码消除,或者使用 tree-shaking 的 rollupjs,那么未使用的导入将被剥离。

I partially agree with the airbnb styleguide to not to use wildcard imports, although javascripts wildcard imports do not suffer from the same diseases as for example pythons or javas wildcard imports, namely it does not pollute the scope with variable names defined in other modules (you can only access them by moduleB.foo, not foowhen using import * as moduleB from ...).

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

About the article on testing: I kindof understand the concerns, but I see nothing that cannot be solved there. You can mock the imports themselves with some custom module loader (a custom amd module loader is literally 15 lines of code), so you dont have to mess with the local scope of the tested module.

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

回答by idmadj

Concerning this part of the question :

关于问题的这一部分:

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

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

Here's how it gets compiled with Babel 6.26:

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

Named

命名

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

... becomes ...

……变成……

'use strict';

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


Wildcard

通配符

import * as Foo from './foo';

... becomes ...

……变成……

'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;
    }
}

In both cases the whole file is imported through require.

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

With wildcards imports, an _interopRequireWildcardfunction is defined and used to assign all exports to the namespace variable.

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

It's worth noting that compiled code will only contain a single _interopRequireWildcarddefinition, and one call to requireand _interopRequireWildcardfor each import.

值得注意的是,编译后的代码将只包含一个_interopRequireWildcard定义,require以及_interopRequireWildcard对每个导入的调用和调用。

Ultimately, the use of wildcard imports will involve a bit more processing at run-time and cause a slight increase in size for the compiled js.

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

回答by Kelly Anderson

Since, with a modern WebPack setup, the two will generate the same compiled/transpiled JS, the real value in named imports is how much more expressive it is. By naming your imports you are telling any one that opens the file which functions from a module you are going to use. An example of where this can be helpful is when writing tests, if mocking is necessary, you have an explicit list of imports to mock.

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

回答by Moeen Basra

I agree with @Tamas.
If you require the full access to all exports in the target file, then you can use the import * as Foo from './foo';or import foo from './foo':

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

but if you need to use specific function or const then better avoid "import *" and be explicit what you needs to do.

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