Open JChehe opened 6 years ago
原文:How to better organize your React applications?
在过去的几年,我一直在开发超大型的 Web 应用。与数十名开发者从零开始,使其现在达到服务数百万用户的规模。如果一开始就没有一个好的文件目录结构,就很难维持代码的组织性。
Nathanael Beisiegel 写了一篇有趣的文章,阐述了他在组织大型 React 项目的策略。但我对其想法并不十分赞同。因此,我决定花些时间找出将来组织 React 项目的最佳方式。
注意 1:在本文提及的所有案例均使用了 Redux。如果你还未了解 Redux,可以阅读 此文档。
注意 2:所有案例均基于 ReactJS,但你可以在 React-Native 应用上使用相同的结构。
写于 2018.04:如果想改善代码结构,那么你应该对我最近写的这篇文章感兴趣——《为何 React 开发者应该懂得模块化》
绝大多数开发者会(或将会)碰到以下场景:
每当客户决定向程序添加新功能时,新代码都会与复杂的遗留代码混合在一起,使得可维护性越来越低。而导致这一切问题的根源在于程序从一开始就没有正确设计。
在刚开始学习 React 时, ,我找了几篇关于如何创建 Todo List 或简单游戏的优秀文章。这些文章让我很好地理解了 React 的基础知识。但与此同时,我很快发现这并没有告诉我如何使用 React 构建真实项目,即包含数十个页面和数百个组件的项目。
在搜索过后,我发现 Github 上所有 React 模板项目均是相类似的结构——根据文件类型组织项目。大概如下:
/src /actions /notifications.js /components /Header /Footer /Notifications /index.js /containers /Home /Login /Notifications /index.js /images /logo.png /reducers /login.js /notifications.js /styles /app.scss /header.scss /home.scss /footer.scss /notifications.scss /utils index.js
这样的文件结构对于构建个人网站或应用应该没多大的问题,但我相信这并不是最佳的目录结构。
当以文件类型组织时,无疑会随着应用的迭代而变得愈发难以维护。当你意识到这一点时已为时已晚,你不得不花费大量的时间和金钱去更改所有东西,或者在接下来的时间忍受着这一问题。
使用 React 的好处是你可以随心所欲地组织项目,而不会强制你按照特定的文件结构。毕竟 React 就是一个简单的 JavaScript 库。
在金融机构工作的那几年,我们将 Ember 作为主要的 JavaScript 框架去构建所有新的 Web 应用。而 Ember 有趣的一点是:能够按照功能组织项目,而不是文件类型。但这足以改变这一切。
Ember 的 Pods 结构很优秀,但仍有局限性,所以我想为其赋予更多的灵活性。在经过数次实验以试图寻找出最佳的目录结构后,我得出这一结论:将所有相关功能组合在一起,然后按需嵌套。以下就是我正在使用的结构:
/src /components /Button /Notifications /components /ButtonDismiss /images /locales /specs /index.js /styles.scss /index.js /styles.scss /scenes /Home /components /ButtonLike /services /processData /index.js /styles.scss /Sign /components /FormField /scenes /Login /Register /locales /specs /index.js /styles.scss /services /api /geolocation /session /actions.js /index.js /reducer.js /users /actions.js /api.js /reducer.js index.js store.js
每个组件、场景(译者注:一般为页面,但也可将登陆和注册两个页面视为一个场景)或服务(功能)均含有供自己使用的所有东西,如自身的样式、图片、译文(译者注:国际化)、actions(译者注:应该指 Redux 相关)和单元/集成测试。即将一项功能视为应用中的一个独立代码段(有点类似 Node 模块)。
为了运行良好,需遵循以下规则:
注意:父级不局限于直系父级,还包含祖先级。不能使用“堂兄弟”的功能,只能将其移到父级内再使用。
下面听我分点阐述。
大家都知道组件是什么。但在此文件结构中,是允许组件嵌套组件。
在项目根目录的 components 文件夹内定义的组件是全局的,即可在应用中的任意位置使用。当在一个组件内定义一个新组件(即嵌套)时,则该新组件就仅能被其直系父级使用。
当开发一个大型应用时,你经常需要创建组件。你明确知道它不会在其他地方复用,但确实需要它。如果你将其放到根目录的 components 文件夹下,久而久之,里面就会填满数百个组件。此时,你意识到需要将它们进行分类,但早已忘了其用途和在哪些地方使用。
如果仅在里面放应用的主要组件,如 button、form field、thumbnail 甚至是一些更复杂的组件,如 listComment、formComposer 及其子组件,那么就能提高查找它们的效率。
案例:
/src /components /Button /index.js /Notifications /components /ButtonDismiss /index.js /actions.js /index.js /reducer.js
场景就是应用中的一个页面。场景其实也是一个组件,但我更乐意将它们放到单独一个文件夹中。
如果有使用 React-Router 或 React Native Router,那么你可以将所有场景引入到 index.js 应用入口文件中,并将它们与路由进行匹配。
既然是组件,那么场景也是可嵌套的,即场景内嵌套场景。当然,也可以在场景内定义组件或服务。但需要记住的是:场景内定义的东西,仅供该场景使用。
/src /scenes /Home /components /ButtonShare /index.js /index.js /Sign /components /ButtonHelp /index.js /scenes /Login /components /Form /index.js /ButtonFacebookLogin /index.js /index.js /Register /index.js /index.js
并不是所有东西都能作为组件。你需要创建一个独立的模块,以供组件和场景使用。
你可以将一项服务看作是独立的模块。它定义了应用的核心业务逻辑,最终可供多个场景,甚至是多个应用(web 与 native 版本 的应用)共享使用。
/src /services /api /services /handleError /index.js /index.js /geolocation /session /actions.js /index.js /reducer.js
我建议你创建一个服务去管理所有 API 请求。即将其作为服务器 API 与视图层(场景和组件)的桥梁/适配器。它可以处理应用发起的网络请求、获取或发布内容、在发送或存储在应用的 store(如 Redux) 前按需处理负载。而场景和组件只需 dispatch actions、读取 store 数据和更新视图即可。
在过去几个月,我已经根据此目录结构开发了一个 React-Native 个人项目,并因此节省了大量时间。所以,将所有相关实体放在一起会让事件变得更简单和更易处理。
这种目录结构只是无数种组织项目的方式之一。但这就是我现在喜欢的方式,希望它能提升你的工作效率!
如果你想查看使用该文件结构的实际工作项目,可查看我 Github 账号:
若有任何疑问,请随时评论或直接与我联系,我将非常乐意提供帮助。
Have fun!
大家好,我是 Alexis!我是一名拥有 14 年开发经验的全栈开发者。我自小就对技术充满激情。现专注于 JavaScript 开发。乐意花费无数时间去学习和使用新技术,并将其用于我们下一个项目中。我最近开始使用 Twitter,欢迎关注我:@alexmngn
原文:How to better organize your React applications?
在过去的几年,我一直在开发超大型的 Web 应用。与数十名开发者从零开始,使其现在达到服务数百万用户的规模。如果一开始就没有一个好的文件目录结构,就很难维持代码的组织性。
Nathanael Beisiegel 写了一篇有趣的文章,阐述了他在组织大型 React 项目的策略。但我对其想法并不十分赞同。因此,我决定花些时间找出将来组织 React 项目的最佳方式。
注意 1:在本文提及的所有案例均使用了 Redux。如果你还未了解 Redux,可以阅读 此文档。
注意 2:所有案例均基于 ReactJS,但你可以在 React-Native 应用上使用相同的结构。
写于 2018.04:如果想改善代码结构,那么你应该对我最近写的这篇文章感兴趣——《为何 React 开发者应该懂得模块化》
构建程序时会遇到什么挑战?
绝大多数开发者会(或将会)碰到以下场景:
每当客户决定向程序添加新功能时,新代码都会与复杂的遗留代码混合在一起,使得可维护性越来越低。而导致这一切问题的根源在于程序从一开始就没有正确设计。
在刚开始学习 React 时, ,我找了几篇关于如何创建 Todo List 或简单游戏的优秀文章。这些文章让我很好地理解了 React 的基础知识。但与此同时,我很快发现这并没有告诉我如何使用 React 构建真实项目,即包含数十个页面和数百个组件的项目。
在搜索过后,我发现 Github 上所有 React 模板项目均是相类似的结构——根据文件类型组织项目。大概如下:
这样的文件结构对于构建个人网站或应用应该没多大的问题,但我相信这并不是最佳的目录结构。
当以文件类型组织时,无疑会随着应用的迭代而变得愈发难以维护。当你意识到这一点时已为时已晚,你不得不花费大量的时间和金钱去更改所有东西,或者在接下来的时间忍受着这一问题。
使用 React 的好处是你可以随心所欲地组织项目,而不会强制你按照特定的文件结构。毕竟 React 就是一个简单的 JavaScript 库。
何为更佳的应用组织方式?
在金融机构工作的那几年,我们将 Ember 作为主要的 JavaScript 框架去构建所有新的 Web 应用。而 Ember 有趣的一点是:能够按照功能组织项目,而不是文件类型。但这足以改变这一切。
Ember 的 Pods 结构很优秀,但仍有局限性,所以我想为其赋予更多的灵活性。在经过数次实验以试图寻找出最佳的目录结构后,我得出这一结论:将所有相关功能组合在一起,然后按需嵌套。以下就是我正在使用的结构:
每个组件、场景(译者注:一般为页面,但也可将登陆和注册两个页面视为一个场景)或服务(功能)均含有供自己使用的所有东西,如自身的样式、图片、译文(译者注:国际化)、actions(译者注:应该指 Redux 相关)和单元/集成测试。即将一项功能视为应用中的一个独立代码段(有点类似 Node 模块)。
为了运行良好,需遵循以下规则:
注意:父级不局限于直系父级,还包含祖先级。不能使用“堂兄弟”的功能,只能将其移到父级内再使用。
下面听我分点阐述。
组件(Components)
大家都知道组件是什么。但在此文件结构中,是允许组件嵌套组件。
在项目根目录的 components 文件夹内定义的组件是全局的,即可在应用中的任意位置使用。当在一个组件内定义一个新组件(即嵌套)时,则该新组件就仅能被其直系父级使用。
为何这么做?
当开发一个大型应用时,你经常需要创建组件。你明确知道它不会在其他地方复用,但确实需要它。如果你将其放到根目录的 components 文件夹下,久而久之,里面就会填满数百个组件。此时,你意识到需要将它们进行分类,但早已忘了其用途和在哪些地方使用。
如果仅在里面放应用的主要组件,如 button、form field、thumbnail 甚至是一些更复杂的组件,如 listComment、formComposer 及其子组件,那么就能提高查找它们的效率。
案例:
场景(Scenes)
场景就是应用中的一个页面。场景其实也是一个组件,但我更乐意将它们放到单独一个文件夹中。
如果有使用 React-Router 或 React Native Router,那么你可以将所有场景引入到 index.js 应用入口文件中,并将它们与路由进行匹配。
既然是组件,那么场景也是可嵌套的,即场景内嵌套场景。当然,也可以在场景内定义组件或服务。但需要记住的是:场景内定义的东西,仅供该场景使用。
案例:
服务(Services)
并不是所有东西都能作为组件。你需要创建一个独立的模块,以供组件和场景使用。
你可以将一项服务看作是独立的模块。它定义了应用的核心业务逻辑,最终可供多个场景,甚至是多个应用(web 与 native 版本 的应用)共享使用。
我建议你创建一个服务去管理所有 API 请求。即将其作为服务器 API 与视图层(场景和组件)的桥梁/适配器。它可以处理应用发起的网络请求、获取或发布内容、在发送或存储在应用的 store(如 Redux) 前按需处理负载。而场景和组件只需 dispatch actions、读取 store 数据和更新视图即可。
总结
在过去几个月,我已经根据此目录结构开发了一个 React-Native 个人项目,并因此节省了大量时间。所以,将所有相关实体放在一起会让事件变得更简单和更易处理。
这种目录结构只是无数种组织项目的方式之一。但这就是我现在喜欢的方式,希望它能提升你的工作效率!
如果你想查看使用该文件结构的实际工作项目,可查看我 Github 账号:
若有任何疑问,请随时评论或直接与我联系,我将非常乐意提供帮助。
Have fun!
我的其他文章
关于我
大家好,我是 Alexis!我是一名拥有 14 年开发经验的全栈开发者。我自小就对技术充满激情。现专注于 JavaScript 开发。乐意花费无数时间去学习和使用新技术,并将其用于我们下一个项目中。我最近开始使用 Twitter,欢迎关注我:@alexmngn