ES6 模块,啥算作第一次导入?

Posted

技术标签:

【中文标题】ES6 模块,啥算作第一次导入?【英文标题】:ES6 module, what counts as the first import?ES6 模块,什么算作第一次导入? 【发布时间】:2020-09-22 05:09:19 【问题描述】:

这是我的模块:

console.log("module imported");
export function call();

在 main.ts 中:

import * as mod from './module';

// other code that doesn't use mod.

我本来希望这会将“模块导入”记录到控制台。事实上,这个例子看起来很漂亮much the same as this one。他们说:

模块代码仅在第一次导入时被评估

但是没有控制台日志。但是,在对 main.ts 进行以下编辑后,会出现日志消息:

import * as mod from './module';

if(false)
  mod.call();

如果只有第一次实际使用模块时才算作第一次导入,这将是有意义的。但是这里的日志消息似乎仅基于静态分析。永远不会执行使用该模块的代码路径。

这是如何工作的?什么算作 ES6 模块的第一次导入?

此外,我的直觉表明这可能与捆绑器有关。它会像这样优化未使用的导入吗?我在一个 react 应用程序中运行这些代码 sn-ps,使用以下命令创建:

npx create-react-app my-app --template typescript
cd my-app
# add the module and import it to index.tsx
npm i
npm run start
# browser opens, check the console

另一方面,typescript react 应用程序也有像 './index.css' 这样的导入,它们只供捆绑程序打包它们。导入某些东西只是因为它的副作用似乎很常见。

我已经搜索了相关问题,但到目前为止还没有找到与此特定问题相关的内容:

Run ES6 code only if module is executed directly `if __name__ == '__main__'` equivalent in javascript es6 modules In browser JS code that imports from ES6 module is not executed

最后一个看起来像是重复的,但它与模块解析中的特定语法错误有关。

【问题讨论】:

【参考方案1】:

您的猜测是正确的,这是由于捆绑程序而发生的。它是捆绑程序的一项功能,称为死代码消除。要了解更多信息,请搜索Tree ShakingDead code elimination

如果您不打算使用导入模块中的任何内容,则模块的源代码将不会包含在您的构建中。

我认为create-react-app 使用Webpack 进行捆绑。如果您想禁用该功能,以development 模式启动应用程序可能会解决它。顺便说一句,在构建时删除未使用的代码是件好事。

【讨论】:

以上是关于ES6 模块,啥算作第一次导入?的主要内容,如果未能解决你的问题,请参考以下文章

使用 es6 模块:未捕获的 ReferenceError:未定义定义

ES6模块化

es6中的模块化

ES6模块化

ES6 模块化

ES6必知必会 —— Module