【问题标题】:What does a sub-path mean in the context of import statements?在 import 语句的上下文中,子路径是什么意思?
【发布时间】:2018-08-31 05:02:25
【问题描述】:

假设我有这样的陈述:

import * as bar from 'foo/bar';

我有几个问题:

  • /bar 位是什么意思?
  • 对此是否有专门的(可通过 Google 搜索的)术语?
  • 这是否可以提高效率(减少模块膨胀)?
  • 如何在 NPM 上捆绑一个 common-js 模块(最好使用 Rollup)并支持这种语法?

【问题讨论】:

    标签: javascript npm import ecmascript-6


    【解决方案1】:

    分解:

    首先为您的第一个和第二个问题提供上下文,让我们进一步分解该陈述的所有部分:

    import * as quux from 'foo/bar';

    注意:您示例中的第一个 bar 实例已故意更改为 quux 以消除以下几点的歧义。

    1. 统称为进口声明,或更具体地说; ECMA-262 Imports Syntax Specification 中定义的进口声明

    2. import 部分称为导入关键字

    3. * as quux 部分称为命名空间导入

      • 星号* 表示bar 中的所有导出绑定都将导入到新创建的名为quux 的命名空间对象。结果是quux 对象将包含从bar 导出的所有成员。
      • 其中的quux 部分称为导入绑定,如前所述,它用作新创建的命名空间对象的名称。
    4. from 'foo/bar' 部分称为From 子句

      • foo/bar 部分是字符串文字,被称为模块说明符...它只是一个文件路径。

    回答您的具体问题:

    1. /bar 位是什么意思?

      它是 Module Specifier 的一部分,它是 From 子句 的一部分。它只是对导出成员将从中导入的文件名的引用。在此示例中,其导出的成员将被导入一个名为 quux 的新命名空间对象。

      关于实际的 "part" 叫什么; ECMA-262 没有为其提供特定的参考/名称,但是,我将该部分称为 filename; (即要导入的模块的文件路径中的文件名).

      据我所知,/bar 可能需要也可能不需要包含文件扩展名(即/bar.js)。 ECMA-262 Imports Syntax 中没有任何内容可以强制执行此操作。 ECMAScript 仅定义模块的语法,而不是加载它们的特定机制。因此,有无 .js 后缀的要求可能因实现而异。例如:

      • 在 Apple 最新的 Safari 浏览器中,该浏览器基于在 iOS 上运行的 WebKit,必须包含 .js 后缀。
      • 在 Node v8.10.0 的 Modules docs 中,他们的示例中确实包含了导入文件的 .js 文件扩展名。 注意:由于 ES6 模块当前有一个 Stability Index 2,这可能会改变。
    2. 是否有一个特定的(谷歌可用的)术语?

      本身不是,因为 ECMA 没有具体命名它。您可以尝试使用谷歌搜索我之前提到的一些术语/命名法。

    3. 这是否能提高效率(减少模块膨胀)?

      我不确定我是否完全理解您所说的 “模块膨胀” 是什么意思。但是,如果您的意思是它会导致应用程序代码中的模块减少吗?我认为不会,这更有可能导致模块的使用量增加。

      原生 ES6 模块支持将提高效率。本机支持本质上可以带来速度/性能的提高。 ES6 模块的其他好处是:

      • ES6 模块是静态可分析的,它允许通过名为 Tree Shaking 的进程消除死/未使用的代码。更多信息 herehere 。所以,如果这就是你所说的“模块膨胀”这个词的意思——那么是的;执行Tree Shaking的工具将删除未使用/无效的代码。

        警告;我不能 100% 确定执行 Tree Shaking 的工具是否能够在 NameSpace Import 中使用通配符/星号 (*) 时删除死代码。 可能需要导入您将使用的特定成员,即

          import { foo, bar, quux } from './foo/bar.js';
        
      • 这是一个官方的 ECMAScript 标准。

      • 您提供的示例包括 NameSpace Import,因此还有另一个好处 - 它有助于避免命名空间冲突。

      • 更多福利提到here

    4. 如何在 NPM 上捆绑一个 common-js 模块(最好使用 Rollup)并支持这种语法?

      Rollup 与名为 @rollup/plugin-commonjs 的插件一起使用,它将 CommonJS 模块转换为 ES6,因此它们可以包含在 Rollup 包中。

    【讨论】:

    • 感谢您的全面回答。我专门在这里问了import * stackoverflow.com/questions/49417236/…
    • 感谢您指出该链接 - 虽然不是结论性的,但似乎 (来自该帖子的答案) 一些 “Tree Shakers” 能够在使用 NameSpace Import 时检测和删除死代码。知道这一点很有用!
    • 关于 NPM 的说明:如果我在 NPM 模块 foo 中发送了一个额外的文件 bar.jsimport 'foo/bar.js'; 会收到吗?
    猜你喜欢
    • 2011-11-08
    • 2011-08-15
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 2023-04-06
    • 1970-01-01
    • 2022-09-28
    相关资源
    最近更新 更多