【问题标题】:How to map from a string to an ES6 import如何从字符串映射到 ES6 导入
【发布时间】:2016-08-25 13:13:20
【问题描述】:

例如。

我们有几个 ES6 模块导入,比如:

import Module1 from './module_1';
import Module2 from './module_2';

我正在使用Babel 将 ES6 转译为 ES5

有另一个函数,它给定一个字符串,返回对导入的 ES6 模块的引用:

getModule(name) {
  switch(name) {
    case "Module 1":
      return Module1;
    case "Module 2":
      return Module2;
    default:
      return null;
  }
}

命名约定非常简单且一致 那么如何去掉手动switch语句呢?

最初我认为,我们可以摆脱使用 eval。类似:

getModule(name) {
  // removes spaces. so "Module 1" to "Module1"
  const ref = name.replace(/\s+/g, "");
  return eval(ref);
}

但是 Babel 改变了变量名等 还把我脚下的地毯扯掉了。

只是为了演示一个未转译的示例适用于:

var foo = function() { console.log("called foo") }
var bar = function() { console.log("called bar") }
eval("foo")() // logs "called foo"
eval("nope") // throws ReferenceError: Can't find variable: nope

是否可以在名为localImports 的文件中获取导入的哈希值?
这样我们就可以写:

getModule(name) {
  // removes spaces. so "Module 1" to "Module1"
  const ref = name.replace(/\s+/g, "");
  return localImports[ref];
}

如何使用 ES6 和 Babel 实现这样的功能?
另外作为奖励,是否可以不使用 eval

【问题讨论】:

  • 你能给出你想要这样做的用例吗?
  • @torazaburo 正在使用 react 根据用户输入渲染组件。输入和组件名称具有直接映射。我正在使用getModule 之类的方法来决定要渲染哪个组件。想利用输入模式,以提高表现力,并确保在 big-ish switch 语句中不存在拼写错误。
  • 首先想到的是进行中间再导出,如export Module1 from '/module1'; export Module2 from './module2';。然后将它们导入为import * as Modules from './reexports';。现在您可以将您的模块称为Modules[module_name]
  • @torazaburo 不错。它自包含在一个单独的文件中,无需手动创建哈希。虽然与stackoverflow.com/questions/39146339/… 有相同的评论。想要从模块引用(例如 Module1)和文件名“module1”自动创建映射。
  • 如果我理解你想要做什么,我认为你不能不访问加载器的内部。

标签: ecmascript-6 babeljs


【解决方案1】:

这对我有用:

导入模块。

import Module1 from './module_1';
import Module2 from './module_2';

使用您想要的任何名称在本地范围内缓存模块。在这种情况下,我使用相同的名称:Module1、Module2。

setModules(){
   this.Module1 = Module1;
   this.Module2 = Module2;
}

使用本地范围内的引用获取对模块的引用。

getModule(name) {
   return this[name]; //e.g. name = 'Module1'
}

【讨论】:

    【解决方案2】:

    如果你使用 Babel 编译 importsrequire,你可以直接使用 require 并制作一个映射:

    const modules = {
      'Module 1': require('./module_1'),
      'Module 2': require('./module_2')
    };
    
    function getModule(name) {
      return modules[name];
    }
    

    【讨论】:

    • require 不是创建映射所必需的。此外,在 OP 的情况下,名称包含空格。
    • @also 想知道 babel 或其他插件 (?) 是否可以为我生成此 modules 哈希。我在我的问题中称它为localImports。在我看来,hash 比 big switch 更清晰,但我不手动维护这个 hash 或 switch 语句的原因是,由于一些愚蠢的错字,键和值可能是错误的。并且很难目视检查大开关或散列
    • @zeroflagL 希望使用来自getModule 的返回值来代替导入。我正在使用 ES6 导入。但与要求相同的区别 - 我猜。顺便说一句,可以使用 name.replace(/\s+/g, "") 之类的方式删除空格
    猜你喜欢
    • 2018-04-27
    • 1970-01-01
    • 2021-11-15
    • 2016-12-09
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多