【问题标题】:How to import everything exported from a file with ES2015 syntax? Is there a wildcard?如何使用 ES2015 语法导入从文件中导出的所有内容?有通配符吗?
【发布时间】:2016-06-03 22:21:30
【问题描述】:

使用 ES2015 语法,我们有了新的导入语法,我一直在试图弄清楚如何将从一个文件导出的所有内容导入到另一个文件中,而无需将其包装在一个对象中,即。如同在同一个文件中定义一样可用。

所以,本质上是这样的:

// constants.js

const MYAPP_BAR = 'bar'
const MYAPP_FOO = 'foo'
// reducers.js

import * from './constants'

console.log(MYAPP_FOO)

这不起作用,至少根据我的 Babel/Webpack 设置,这种语法无效。

替代方案

这行得通(但如果您需要导入的东西不止几件,这会很长而且很烦人):

// reducers.js

import { MYAPP_BAR, MYAPP_FOO } from './constants'

console.log(MYAPP_FOO)

就像这样(但它将常量包装在一个对象中):

// reducers.js

import * as consts from './constants'

console.log(consts.MYAPP_FOO)

第一个变体是否有语法,或者您必须按名称导入每个事物,还是使用包装器对象?

【问题讨论】:

  • 想象import * from 是可能的。如果reducers.js 包含变量MYAPP_FOO 会发生什么?或者如果另一个模块也包含MYAPP_FOO?还有更多需要考虑的事情。这不是一个好主意。
  • 它的缺失无疑使静态分析更容易,因此可以说使用这种语法将是一种反模式。即便如此,它偶尔也会派上用场。

标签: javascript ecmascript-6 es6-module-loader


【解决方案1】:

您不能通过通配符为第一个变体导入所有变量,因为如果您在不同文件中具有相同的名称,它会导致变量冲突。

//a.js
export const MY_VAR = 1;

//b.js
export const MY_VAR = 2;


//index.js
import * from './a.js';
import * from './b.js';

console.log(MY_VAR); // which value should be there?

因为这里我们无法解析MY_VAR的实际值,所以这种导入是不可能的。

对于您的情况,如果您有很多值要导入,最好将它们全部导出为对象:

// reducers.js

import * as constants from './constants'

console.log(constants.MYAPP_FOO)

【讨论】:

  • 好吧,通配符导入在 python 中工作:对a.js 的引用被破坏并使用b.js。为什么这在 JS 中不起作用?
  • 我认为这也很危险。假设您来自一些第三方库的import *。 LibA 有你想要的 foo,而 LibB 没有任何 foo。几个月或几年后,LibB 添加了一个 foo 组件,它破坏了 LibA 的 foo。突然你的代码坏了。 LibB 甚至可能不认为添加 foo 是一项重大变化,因为它以前不存在。
  • @noɥʇʎԀʎzɐɹƆ 因为您可能无法控制 a.jsb.js 的实现,所以您无法防止名称冲突。正如@error 所指出的,特别是在未来。
【解决方案2】:

第一个变体有语法吗,

没有。

或者您必须按名称导入每个事物,还是使用包装器对象?

是的。

【讨论】:

  • 详细说明,请参阅with
  • with 完全不相关:这是一个坏主意,因为它依赖于动态值。 imports 是静态的,因此可以定义所有导出的名称。注意 (1) 使用 dynamic 导入会遇到与with 相同的问题; (2) 覆盖导入的名称当然是个坏主意,但它可能会抛出错误,这也有问题,这就是为什么所有这些都没有完成,但它们比with 微妙得多。
【解决方案3】:

你可以导入对象,遍历它的属性,然后像这样使用 eval 手动生成常量

import constants from './constants.js'

for (const c in constants) {
  eval(`const ${c} = ${constants[c]}`)
}

不幸的是,这个解决方案不适用于我的 IDE 中的智能感知,因为常量是在执行期间动态生成的。但它应该可以正常工作。

【讨论】:

    【解决方案4】:

    当然有。

    只需使用 codegen.macro

    codegen
          'const { ' + Object.keys(require('./path/to/file')).join(',') + '} = require("./path/to/file");
    

    但似乎您无法导入由 codegen 生成的变量。 https://github.com/kentcdodds/babel-plugin-codegen/issues/10

    【讨论】:

      【解决方案5】:

      在 ES6 中,通过以下代码,可以在没有 wrap 对象的情况下使用导入的内容。

      把它放在这里给像我这样在此处结束搜索的人。

      constants.js:

      export const A = 2;
      export const B = 0.01; 
      export const C = 0.04;
      

      main.js:

      import * as constants from './constants'
      const {
          A,
          B,
          C,
      } = constants;
      

      【讨论】:

      • import { A, B, C } from './constants' 的较长版本。
      猜你喜欢
      • 2018-12-06
      • 2015-08-06
      • 2012-12-08
      • 2019-01-02
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 2018-01-09
      • 2018-10-30
      相关资源
      最近更新 更多