【问题标题】:Why fromClause in import statement expects string literal?为什么 import 语句中的 fromClause 需要字符串文字?
【发布时间】:2017-08-10 17:38:05
【问题描述】:

在我们之前的 node.js 应用程序(基于 ES5)中,我们很难在 require 语句中使用相对路径。

例如:var conf = require('../../global/config');

相对路径的问题在代码混淆中被冒泡了。我们不得不花费大量时间来处理这个问题。

有了这个经验,在我们当前的 node.js 应用程序(基于 ES6)中,虽然我不确定我们是否会混淆代码,但我不想使用相对路径。因此,我在每个文件中创建了一个 const ROOTDIR 并为其分配了项目的绝对路径。然后意识到 import 在它的 fromClause 中只需要静态文字。通过强制输入(复制/粘贴)每个 import 的完整路径或使用相对路径返回或使用 require 语句,这让生活变得困难。

虽然我试图了解使用 import 样式的好处,但我需要一些帮助来理解以下 3 点。

  1. 使用import除了类似java/.net的编码风格还有什么好处?

  2. 为什么 import 只接受字符串文字?似乎是设计使然,如果是这样,为什么?

  3. 如果我想import一个基于某些条件的模块,我将不得不去require,因为我不能使用import if/elseswitch 语句中。有什么解决方案/黑客吗?

感谢所有帮助。

【问题讨论】:

  • 您的目标是 node.js,不是吗? require 是特定于节点的 afaik
  • @Psi 是的,更新了描述和标签。感谢您指出。

标签: javascript node.js ecmascript-6


【解决方案1】:

首先,请记住 import 目前不受任何环境支持,包括 Node.js。所以你可能会使用一个转译器,比如 Babel,它会假设一个 CommonJS 环境(比如 Node)并使用require 填充。

importrequire 不同,它被设计为静态分析。也就是说,您的代码可以在不运行的情况下进行分析,并且可以知道需要加载哪些模块。

这意味着:

  1. import 声明被提升。无论在何处声明它们,它们实际上都存在于文件的最顶部。
  2. 因此将它们放在块中是无效的。
  3. 因此将它们放在条件句中是无效的。
  4. import 语句之前的文件中不能存在任何内容,因此不能使用任何变量(包括常量),因为在运行import 语句时它们将不存在。

由于可以对代码进行静态分析,这将在将来简化捆绑代码的过程。可以准确地确定需要包含哪些代码,这意味着可以更轻松地编译您的代码以进行分发。例如,如果浏览器请求一个带有import 语句的JS 文件,服务器可以看到它并将两者打包在一起。这还有很长的路要走,但很可能就是未来!

【讨论】:

  • 是的,我在我们的 Node.js 环境中使用了转译器 (Babel)。好吧,我在第一行定义了一个 const 并在 require 中使用了它。我在同一个文件中也有 import 语句,这些语句在 require 语句之后。它没有任何错误/警告。例如:const ROOTDIR = '/absolute/path/to/project/directory'。如果我理解您的回复,那是因为编译器将其更改为 ES5,或者它不是原生 ES6 环境。我说的对吗?
  • @GaneshAdapa 看转译的代码!它会给出比我更好的解释。
  • 非常感谢。我今天会过一遍转译后的代码。
  • javascript 中是否还有其他旨在进行静态分析的功能,或者仅此一项?
  • @tjb 大部分 JS 都可以静态分析。 require 在这方面是/不寻常的。
【解决方案2】:

importrequire 之间的主要区别在于,使用 import,您拥有静态依赖项,浏览器在 解析您的代码时会解析这些依赖项,而使用 require,您拥有动态依赖项当 Node.js 运行您的代码时会解决这些问题。

静态导入的优点是代码更容易被 JavaScript 引擎优化。例如,webpack 使用它从导入的模块中删除不需要创建更小的包(称为摇树)的代码。

正如您所指出的,这样做的缺点是您不能在“from”之后使用动态表达式,因为这只能在运行时解决。所以这确实是设计使然。

它周围没有“hack”,如果你必须有一个在运行时解析的动态依赖,你需要使用“require”。

【讨论】:

    猜你喜欢
    • 2020-10-12
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    相关资源
    最近更新 更多