全部 / 前端 / 后端 / 技术 · 2022年5月15日 0

你为何要避免使用 index.js ?

2022-05-15+15_19_50

在很多 JavaScript 项目中,不管是前端 React 项目,还是后端 node.js 项目你可以通过一个 index.js 文件来聚合所有的导入。在一个文件中导出所有相关的 exports 会方便许多,接着其它文件可以从这个文件中导入内容。它看上去简洁,但可能会很快失控。

TLDR:

为何你应该避免聚合所有的导入到一个文件 index.js 中?

  1. 循环引用;
  2. 使用动态导入时的意外导入;
  3. nodejs 的作者也说要避免使用;

什么时候可以 index.js ?

当你创建 npm 包时,建议使用 index.js 。

典型的 index.js 长什么样子?

典型的 index.js 文件像下面这样,可以聚合所有的导出在一个文件中。

1. 循环引用

虽然时间的推移 index.js 文件变得越来越大,此时一位开发者利用自动引入功能,在一个相邻文件中引入了 index.js 中的内容。

现在,该开发者又通过 index.js 文件导出了一些内容,就像其他人做的一样。

现在问题是什么?他制造了一个循环引用。

什么?"composition.js" 从 "index.js" 中导入 Items,"index.js" 导入了 "composition.js" 中的 "CompostionsOfItems" 并导出。

composition.js → index.js → composition.js

现在,一个(例如,items.js)从 index.js 文件中导入一些变量的文件将会抛出错误:cannot read property "Item1" of undefined

一些编译工具可以应付这种循环导入(例如:带有 babel 的 webpack),但是其他例子(jest + ts-jest、jest + bable)的编译无法处理这种问题,将会抛出不清晰的错误信息。这很难调试但是当你知道避免使用 index.js 时,此种问题将会很少。

问题:那我们该如何做 ?

回答: 避免使用 index.js 同时只从文件中引入你需要的内容。在我们这个例子中,从 items.js 中引入 Item1 和 Item2 就不会产生问题。

避免使用 index.js 并不能保证不会产生循环引用,你必须把导入语句组织成一个树状结构。

避免循环引用的另一种方法是使用 eslint-plugin-import 中的 Eslint no-cycle 规则:

2. 使用动态导入时的意外导入

当在写前端项目时,通常是要考虑使用动态导入来分割代码。例如:在 React 中你可以使用 React.lazy() 使代码分割为多块。使用哪个框架并不重要,但我们以写 react app 为例,你把所有的 routes 整洁的聚合与 routes.js 文件中:

// routes.js
export Route1 from 'route1'
export Route2 from 'route2'
export Route3 from 'route3'
export Route4 from 'route4'

若你打算利用懒加载来使你的应用更快,你可能会写出下面的代码:

const LazyRoute1 = React.lazy(() => import('./routes').then(module => ({ default: module.Route1 }));

罪魁祸首是什么?你实际上是一次性请求了所有的路由而不是只按需加载了 Route1 ,导致使用了比预期更多的带宽同时也使懒加载和代码分割功能失效。

3. nodejs 的作者也说避免使用 index.js

在 JSConf EU 的会议上,nodejs 的作者 Ryan Dahl 演示了关于 nodejs 的 10 件遗憾的事,其中一个就是 index.js 文件。那是一个很好的演讲我建议你看下:

总结:10 Things I Regret About Node.js — Ryan Dahl

视频:10 Things I Regret About Node.js – Ryan Dahl – JSConf EU

什么时候你应该使用 index.js ?

如果你创建了一个开源的包同时希望导出公共模块,通常是使用一个文件来暴露出所有需要导出的东西。

另外我个人加一个非作者所写,就是当搜文件或文件编辑器里打开了很多 index.js 时,会让我抓狂,根本不知道打开了什么文件:

我的个人建议是:业务代码中少用 index.js 来组织代码

原文链接:https://medium.com/@alonmiz1234/why-you-should-avoid-index-js-3321a9902120