我在我继承的一些代码上看到了一种模式。每个目录都有自己的 JS 文件,但也有一个 index.js,它实际上从另一个或多个 JS 文件导出项目。
我认为这样做是为了让您可以准确地看到要导出的内容,因为主要导出在 index.js 中,而主要代码在其他 js 文件中。
这个对吗?这种模式叫什么?
我应该继续使用这种模式吗?
我在我继承的一些代码上看到了一种模式。每个目录都有自己的 JS 文件,但也有一个 index.js,它实际上从另一个或多个 JS 文件导出项目。
我认为这样做是为了让您可以准确地看到要导出的内容,因为主要导出在 index.js 中,而主要代码在其他 js 文件中。
这个对吗?这种模式叫什么?
我应该继续使用这种模式吗?
假设我有以下目录结构:
MyApp
├── app.js
├── test.js
├── package.json
├─┬ controllers
│ ├── index.js
│ ├── signIn.js
│ └── signOut.js
└─┬ views
├── index.js
├── signIn.js
└── signOut.js
将以下代码放入index.js
文件中...
// index.js
module.exports = {
signIn: require('./signIn')
, signOut: require('./signOut')
};
...允许您访问require
整个目录,例如...
// test.js
describe('controllers', () => {
// ~/controllers/index.js
const controllers = require('./controllers');
it('performs a sign-in', () => {
...
});
it('performs a sign-out', () => {
...
});
});
另一种方法是分别对require
每个文件。
index.js
不需要在目录中。您可能require
在一个目录中没有一个文件index.js
都一样。
// app.js
const signOut = require('./controllers/signOut.js')
但是,随着您的应用程序的增长,它会变得乏味。我使用一个包,require-directory
因为在目录中键入每个文件也很乏味并且容易出错。
// index.js
module.exports = require('require-directory')(module);
/*
This yields the same result as:
module.exports = {
signIn: require('./signIn')
, signOut: require('./signOut')
, ...
};
*/
鉴于这两种常见的结构类型...
MyApp
│ // files divided per type (controllers, components, actions, ...)
├─┬ actions
│ ├── index.js
│ ├── signIn.js
│ └── signOut.js
├─┬ components ...
├─┬ reducers ...
├─┬ pages ...
│
│ // files divided per component
├─┬ components ...
│ ├── index.js
│ ├── SimpleComponent.jsx
│ ├── AnotherComponent.duck.jsx // redux "duck" pattern
│ ├─┬ ComplexComponent // large complex logic, own actions, stylesheet, etc.
│ ...
├─┬ pages ...
│ ├── index.js
│ ├─┬ App
│ │ ├── index.js // not necessary here, matter of habit
│ │ ├── App.jsx
│ │ ├── actions.js
│ │ └── reducer.js
│ └─┬ Dashboard
├── another.js
...
another.js
您可以像这样简单地导入文件
import {signIn, signOut} from './actions'
import {App} from './pages'
import {ComplexComponent} from './components'
而不是这个(没有index.js
文件)
import {signIn} from './actions/signIn'
import {signOut} from './actions/signOut'
import {App} from './pages/App/App' //notice the redundancy here
import {ComplexComponent} from './components/ComplexComponent/ComplexComponent'
ECMAScript 6 模块
导入 - JavaScript | MDN
Babel 转译器 - 现在为您的浏览器带来新的导入
构建 React 项目
React Redux “鸭子模式” - 组件的单文件方法
其他答案提供了很多很好的信息,但是要尝试专门回答您的问题“我应该继续使用这种模式”,我会说不,至少在大多数情况下。
问题是,这种模式需要额外的努力,因为您必须维护这些额外的index.js
文件。根据我的经验,这种努力比简单地编写一个目录更长的import
语句要大。另外,您可以index.js
通过使用类似require-dir
.
话虽如此,如果您正在创建一个将被大量人员使用的库,例如大型编程部门的关键模块或公共 NPM 模块,那么您的努力index.js
变得更加合理。只要你有足够多的人使用你的模块,你的用户将(累积地)从你添加它们中节省更多的时间,而不是你失去维护它们的时间。
我将直接深入探讨您是否使用此模式的问题(因为其他答案不足以解决此问题)。
假设代码中的每个目录都代表一个独立模块(不依赖另一个模块工作)。使用这种模式将带来以下优势:
这样做的问题:
循环依赖是非常有问题的,使用导入整个模块/目录index.js
将导入其所有部分(在 中声明index.js
)所以如果你有:
-- moduleA
├-- comp1A // needs comp1B
├-- comp2A
└-- index.js // export both comp1/2
-- moduleB
├-- comp1B
├-- comp2B // needs comp2A
└-- index.js // export both comp1/2
示例案例 -comp1A
需要来自的东西,comp1B
而comp2B
需要来自的东西comp2A
导入特定文件(不带index.js
- import something from './moduleB/comp1B'
)时,您不会有循环依赖。
但是如果你使用index.js
( import something from './moduleB'
) 你会有循环依赖。
我的建议是index.js
在正确的地方使用,并保持它们的维护!与小模块一起使用index.js
将是完美的,但随着时间的推移它们会增长并且应该被分割。index.js
在 common/shared/utils/misc/core (当你想放置在整个项目中使用的未分类和不相关的代码时,不管你怎么称呼它)模块使用是非常糟糕的。
那这个呢?
module.exports = {
...require('./moduleA'),
...require('./moduleB')
}
(moduleA.a 将被 moduleB.a 覆盖)