通配符或星号(*)与命名或选择性导入es6 javascript
只是想知道使用导入的最佳方式是:通配符或星号(*)与命名或选择性导入es6 javascript,javascript,import,ecmascript-6,wildcard,es6-modules,Javascript,Import,Ecmascript 6,Wildcard,Es6 Modules,只是想知道使用导入的最佳方式是: import*作为来自'/Foo'的Foo VS: 从'/foo'导入{bar,bar2,bar3} 就效率而言,比如说,我使用webpack捆绑所有JavaScript文件。即使我没有在主代码中使用它们,第一个是否会真正导入所有内容 我可以找到一些参考资料: 在中,他们建议不使用通配符,因此将始终存在默认的导入对象。如果您使用带有新uglify提供的死代码消除功能的webpack,或带有树抖动功能的rollupjs,则未使用的导入将被剥离 我部分同意airbn
import*作为来自'/Foo'的Foo代码>
VS:
从'/foo'导入{bar,bar2,bar3}代码>
就效率而言,比如说,我使用webpack捆绑所有JavaScript文件。即使我没有在主代码中使用它们,第一个是否会真正导入所有内容
我可以找到一些参考资料:
在中,他们建议不使用通配符,因此将始终存在默认的导入对象。如果您使用带有新uglify提供的死代码消除功能的webpack,或带有树抖动功能的rollupjs,则未使用的导入将被剥离
我部分同意airbnb styleguide不使用通配符导入,尽管javascripts通配符导入不会遭受与pythons或javas通配符导入相同的疾病,即它不会污染其他模块中定义的变量名称的范围(您只能通过moduleB.foo
访问它们,在使用import*as moduleB from…
时,不能通过foo
访问它们)
关于关于测试的文章:我有点理解这些问题,但我认为没有什么是无法解决的。你可以用一些自定义模块加载器(自定义amd模块加载器实际上是15行代码)来模拟导入本身,这样你就不必弄乱被测模块的本地范围。我同意@Tamas。
如果需要完全访问目标文件中的所有导出,则可以使用“/Foo”中的import*as Foo;
或
从“/foo”导入foo:
但是,如果您需要使用特定的函数或常量,那么最好避免“导入*”,并明确您需要执行的操作。关于问题的这一部分:
即使我没有在主代码中使用它们,第一个是否会真正导入所有内容
以下是使用Babel 6.26编译的过程:
命名
…变成
'use strict';
var _foo = require('./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;
}
}
通配符
…变成
'use strict';
var _foo = require('./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
导入的
通过通配符导入,定义了一个\u interopRequireWildcard
函数,用于将所有导出分配给名称空间变量
值得注意的是,编译后的代码只包含一个\u interopRequireWildcard
定义,以及每次导入时对require
和\u interopRequireWildcard
的一个调用
最终,通配符导入的使用将在运行时涉及更多的处理,并导致编译后的js的大小略有增加。因为,使用现代的WebPack设置,两者将生成相同的编译/传输js,命名导入的真正价值在于它的表现力有多强。通过命名导入,你就知道了任何一个打开的文件都可以从您将要使用的模块中运行。例如,在编写测试时,如果需要模拟,您将有一个要模拟的导入的显式列表。如果我import*作为Foo from./Foo'
,并且我只使用Foo.bar
,那么Foo.bar2
和Foo.bar3
是否会被作为死代码删除?@bsapaka是的,如果Foo.bar2
和Foo.bar3
根本没有使用。我在哪里可以阅读更多关于这方面的信息?例如,官方文档或github发行线程。可能重复