只是想知道哪一个是使用导入的最佳方式:
import * as Foo from './foo';
VS
import { bar, bar2, bar3 } from './foo';
就效率而言,例如,我正在使用webpack捆绑所有JavaScript文件。即使我没有在主代码中使用它们,第一个实际上会导入所有内容吗?
我能找到的一些参考文献是:
在Airbnb style guide中,他们建议不要使用通配符,因此始终会有默认导入对象和this。
答案 0 :(得分:16)
如果您使用带有新uglify提供的死代码消除的webpack,或者使用树状抖动的rollupjs,那么将删除未使用的导入。
我部分同意airbnb样式指南不使用通配符导入,尽管javascripts通配符导入不会遇到与pythons或javas通配符导入相同的疾病,即它不会使用其他定义的变量名来污染范围模块(使用moduleB.foo
时,您只能foo
访问它们,而不是import * as moduleB from ...
。
关于测试的文章:我很了解这些问题,但我看不出那里无法解决的问题。您可以使用一些自定义模块加载器来模拟导入(自定义模块加载器实际上是15行代码),因此您不必弄乱测试模块的本地范围。
答案 1 :(得分:11)
关于这部分问题:
即使我没有在主代码中使用它们,第一个实际上会导入所有内容吗?
以下是使用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的大小略有增加。
答案 2 :(得分:4)
我同意@Tamas
如果您需要对目标文件中的所有导出的完全访问权限,则可以使用<div class="all">
<div class="header">All</div>
<div class="cell-1"></div>
<div class="cell-2"></div>
<div class="cell-3"></div>
<div class="cell-4"></div>
</div>
<div class="first">
<div class="header">First</div>
<div class="cell-1"></div>
<div class="cell-2"></div>
<div class="cell-3"></div>
<div class="cell-4"></div>
</div>
<div class="second">
<div class="header">Second</div>
<div class="cell-1"></div>
<div class="cell-2"></div>
<div class="cell-3"></div>
<div class="cell-4"></div>
</div>
<div class="third">
<div class="header">Third</div>
<div class="cell-1"></div>
<div class="cell-2"></div>
<div class="cell-3"></div>
<div class="cell-4"></div>
</div>
要么
import * as Foo from './foo';
但是如果你需要使用特定的函数或const,那么最好避免使用“import *”并明确你需要做什么。
答案 3 :(得分:0)
由于使用现代WebPack设置,两者将生成相同的编译/转换JS,命名导入的真正价值在于它的表现力。通过命名您的导入,您可以告诉任何一个打开文件的文件,该文件的功能来自您将要使用的模块。这可能有用的一个示例是在编写测试时,如果需要进行模拟,则您有一个明确的模拟导入列表。