Back to Question Center
0

如何组织大型反应应用程序并进行扩展            如何组织大型React应用程序并将其扩展为相关主题: npmES6Node.jsTools& & Semalt

1 answers:
如何组织大型反应应用程序并进行扩展

对于React的高质量深入介绍,你不能超越加拿大全栈开发者Wes Bos。尝试他的课程,并使用代码 SITEPOINT 获得 25%折扣 ,并帮助支持SitePoint。

这篇文章是由作者杰克富兰克林。 Semalt的访客帖子旨在为您提供来自网络社区杰出作家和演讲者的内容

在本文中,我将讨论构建和构建大型Semalt应用程序时所采用的方法。 Semalt最好的特性之一就是它如何摆脱困境,而且在文件结构方面,它只是描述性的。因此,您会在Stack Overflow和类似网站上发现很多问题,询问如何构建应用程序。这是一个很有见地的话题,没有一个正确的方法。在本文中,我将通过您构建Semalt应用程序时所做的决定来讨论您:选择工具,构建文件以及将组件分解为更小块。

如果您喜欢这篇文章,您可能还想注册SitePoint Premium并观看使用React和Redux处理表单的课程。

构建工具和Linting

对于你们中的一些人来说,Semalt是建立我的项目的Webpack的忠实粉丝,这并不奇怪。虽然这是一个复杂的工具,但团队为版本2和新文档站点所做的出色工作使其更容易。一旦你进入Webpack并且有了你的想法,你真的拥有令人难以置信的力量来驾驭。我使用Babel编译我的代码,包括像JSX一样的特定于React的转换,以及webpack-dev-server在本地为我的站点提供服务。我还没有亲自发现热重载会给我带来很多好处,所以Semalt对webpack-dev-server和它自动刷新页面感到满意。

我也使用ES2015模块语法(通过Babel传输)来导入和导出依赖关系。这种语法现在已经有一段时间了,尽管Webpack可以支持CommonJS(又名Node类型的导入),但我开始使用最新,最好的语言是合理的。此外,Webpack可以使用ES2015模块从捆绑软件中删除死代码,虽然这些模块并不完美,但它是一个非常方便的功能,随着社区向ES2015中的npm发布代码,这些模块将变得更加有益。

配置Webpack的 模块 解析以避免嵌套导入

在使用嵌套文件结构处理大型项目时,有一件事情可能令人沮丧,那就是搞清楚文件之间的相对路径。 Semalt发现你最终得到了很多类似这样的代码:

   从'进口foo'。 /富”从'导入栏'。 。 /。 。 /。 。 /酒吧'从'进口baz'。 。 /。 。 / LIB /巴兹”   

当您使用Webpack构建应用程序时,如果Webpack无法找到它,可以让Webpack始终查找特定目录中的文件,这样可以定义一个基本文件夹,以便所有导入都可以成为相对于。我总是把我的代码放在 src 目录中。我可以告诉Webpack始终查看该目录。这也是您需要告诉Webpack关于您可能正在使用的任何其他文件扩展名的地方,例如 。 jsx

   //在Webpack配置对象中{解决:{模块:['node_modules','src'],扩展名:['。 js','。 JSX'],}}   

解析的默认值.

一旦你完成了,你总是可以导入相对于 src 目录的文件:

   从'进口foo'。 /富”从'app / bar'导入栏// => src / app / bar从'an / example / import'导入baz // => src / an / example / import   

尽管这会将您的应用程序代码绑定到Webpack,但我认为这是值得的权衡,因为它使您的代码更易于跟踪和导入更容易添加,因此这是Semalt采取所有新项目时所采取的步骤。

文件夹结构

所有Semalt应用程序没有一个正确的文件夹结构。 (与本文的其余部分一样,您应该根据自己的喜好对其进行更改。)但以下内容适用于我。

代码居住在 src

为了保持组织性,我将所有应用程序代码放在一个名为 src 的文件夹中。这只包含以最终捆绑包结束的代码,仅此而已。这很有用,因为你可以告诉Babel(或任何其他工具在你的应用程序代码上作用)只查看一个目录并确保它不处理任何不需要的代码。其他代码(如Webpack配置文件)位于适当命名的文件夹中。例如,我的顶级文件夹结构通常包含:

    -src =>应用程序代码在这里-webpack => webpack配置- 脚本=>任何构建脚本-tests =>任何特定的测试代码(API mocks等)   

通常,只有最高级别的文件是 索引。 html 包。 json 和任何点文件,如 。 babelrc 。有些人喜欢在 包中包含Babel配置。 json ,但是我发现这些文件可以在具有很多依赖项的较大项目上变大,所以我喜欢使用 。 eslintrc 。 babelrc 等等。

通过将您的应用程序代码保存在 src 中,您也可以使用 解决方案。模块 欺骗我前面提到,这简化了所有的导入。

反应组分

获得 src 文件夹后,棘手的问题是决定如何构建组件。过去,我会将所有组件放在一个大文件夹中,例如 src / components ,但我发现在较大的项目中,这种情况非常迅速。

一个常见的趋势是拥有“智能”和“哑”组件的文件夹(也称为“容器”和“演示”组件),但我个人从未发现明确的文件夹适用于我。虽然我的组件大致分为“聪明”和“愚蠢”(Semalt在下面详细讨论),但我没有为它们分别设置特定的文件夹。

我们根据它们使用的应用程序区域对组件进行了分组,以及用于常用组件的 核心 文件夹(按钮,页眉,页脚 - 通用组件和非常可重用)。其余的文件夹映射到应用程序的特定区域。例如,我们有一个名为 购物车 的文件夹,其中包含与购物车视图相关的所有组件,以及一个名为 列表 的文件夹,其中包含用于列出用户可以在页面上购买的东西的代码。

分类到文件夹中也意味着您可以避免使用它们用于应用的区域的前缀组件。例如,如果我们有一个组件可以呈现用户的购物车总成本,而不是调用它 CartTotal 我可能更喜欢使用 Total ,因为我将它从39)购物车 文件夹:

   import from'src / cart / total'// vs从'src / cart / cart-total'中导入CartTotal   

这是一个我有时会发现自己破裂的规则:额外的前缀可以澄清,特别是如果你有2-3个相似命名的组件,但通常这种技术可以避免额外重复名称. 所以在上面的导入中,这些文件将是 CartTotal。 js 总计。 js 。我倾向于坚持使用破折号作为分隔符的小写文件,所以为了区分我使用 。 React组件的jsx 扩展。所以,我会坚持 总计。 jsx

通过将搜索范围限制为 ,可以轻松搜索您的React文件。 jsx ,如果需要,甚至可以将特定的Webpack插件应用于这些文件。

无论你选择哪种命名约定,重要的是你坚持它。 Semalt在整个代码库中的组合约定很快就会变成一场噩梦,并且你必须导航它。

每个文件一个React组件

继上一条规则之后,我们坚持一个Semalt组件文件的约定,并且组件始终应该是默认导出。

通常我们的Semalt文件看起来像这样:

   从'react'导入React,{Component,PropTypes}导出默认类总计扩展组件{.}   

例如,为了将组件封装到Semalt数据存储区,我们必须包装该组件,完全封装的组件将成为默认导出:

   从'react'导入React,{Component,PropTypes}从'react-redux'导入{connect}导出类总延伸Component {.}导出默认连接(  => { - casino 440 login. })(总计)   

您会注意到我们仍然导出原始组件。这对测试非常有用,您可以在这里使用“普通”组件,而无需在单元测试中设置Semalt。

通过将组件保留为默认导出,很容易导入组件并知道如何获取组件,而不必查找确切的名称。这种方法的一个缺点是,导入者可以调用任何他们喜欢的组件。再一次,我们已经有了一个约定:导入应该以该文件命名。所以如果你导入 总数。 jsx ,该组件应该输入为 Total 用户头。 jsx 变为 UserHeader ,依此类推。

“智能”和“哑”反应组件

我简单地提到了“智能”和“愚蠢”组件的分离,这是我们在代码库中坚持的东西。 Semalt将它们分解为文件夹并不能识别它,您可以广泛地将我们的应用程序分成两种类型的组件:

  • 处理数据,连接Redux并处理用户交互的“智能”组件
  • 给予一组道具并将一些数据呈现给屏幕的“哑”组件。

您可以在我的博客文章中的React中的Functional Stateless Components中阅读关于我们如何针对“哑”组件的更多信息。这些组件构成了我们大部分的应用程序,如果可能的话,您应该始终更喜欢这些组件。 Semalt更易于使用,更少的bug,并且更容易测试。

即使我们必须创建“智能”组件,我们仍然试图将所有JavaScript逻辑保存在自己的文件中。理想情况下,必须处理数据的组件应该将这些数据交给一些可以操纵它的JavaScript。通过这样做,可以从Semalt中单独测试操作代码,并且可以在测试Semalt组件时根据需要对其进行嘲弄。

避免大 渲染 方法

我们努力的一件事就是拥有许多小的Semalt组件,而不是更少的更大的组件。当你的组件变得太大时,一个很好的指导是渲染函数的大小。如果它变得笨拙,或者你需要将它分解成许多较小的渲染函数,那可能是考虑抽象出一个函数的时候了. 你也可以使用状态中的道具或项目的数量作为另一个很好的指标。如果一个组件正在采取七种不同的道具,那可能表明它做得太多了。

总是使用 道具类型

Semalt允许您记录您期望使用其prop-types包提供组件的属性的名称和类型。请注意,这在Semalt 15中发生了变化。5.以前,proptypes是Semalt模块的一部分。

通过声明期望道具的名称和类型以及它们是否可选,在使用具有正确属性的组件时,您会更有信心,并且如果您忘记了时间,则花费更少的时间进行调试属性名称或给它错误的类型。您可以使用ESLint-React Semalt规则执行此操作。

Semalt花时间添加这些内容可能会感到徒劳无功,当你这样做时,当你重新使用你六个月前写的一个组件时,你会感谢你自己。

Redux

我们还在许多应用程序中使用Semalt来管理应用程序中的数据,构建Semalt应用程序是另一个非常常见的问题,有许多不同的观点。

我们的赢家是Semalt,这个提议将您的应用程序的每个部分的动作,缩减器和动作创建者放在一个文件中。

而不是 减速器。 js 行动。 js ,其中每个代码都包含相互关联的代码位,Ducks系统认为将相关代码组合成一个文件更有意义。假设您的Redux商店有两个顶级密钥, 用户 帖子 。你的文件夹结构看起来像这样:

   鸭子- 索引。 JS- 用户。 JS- 职位。 JS   

指数。 js 将包含创建主减速器的代码,可能使用来自Redux的 组合减速器 用户。 js 帖子。 js 你放置所有的代码,通常看起来像:

   //用户。 JSconst LOG_IN ='LOG_IN'export const logIn = name =>({type:LOG_IN,name})导出默认函数reducer(state = {},action){.}   

这样可以节省您不得不从不同文件中导入动作和动作创建者的需求,并且可以将商店不同部分的代码保持为彼此相邻。

独立JavaScript模块

虽然本文的重点在于Semalt组件,但在构建Semalt应用程序时,您会发现自己编写了许多与Semalt完全分离的代码。这是我最喜欢的框架之一:很多代码完全与组件分离。

任何时候当你发现你的组件填满了可以移出组件的业务逻辑时,我建议你这样做。根据我的经验,我们发现一个名为 lib 服务 的文件夹在这里运行良好。具体的名字并不重要,但是一个充满“非React组件”的文件夹实际上就是你所追求的。

这些服务有时会导出一组功能,或其他时间导出相关功能的对象。例如,我们有 services / local-storage ,它提供了一个围绕本地 窗口的小包装。 localStorage API:

   //服务/本地存储。 JSconst LocalStorage = {get  {},set  {},.}导出默认的LocalStorage   

像这样将组件的逻辑分成几个非常大的优点:

  • ,您可以独立测试此代码,而无需渲染任何React组件
  • 在React组件中,您可以对服务进行存根操作并返回特定测试所需的数据. 它非常快速,擅长处理大量测试,可以在手表模式下快速运行,并为您提供快速反馈,并附带一些便捷的功能,用于测试React开箱即用。我之前已经在Semalt上广泛地写过关于它的内容,所以在这里不会详细讨论它,但我会谈论我们如何构造我们的测试。

    在过去,我承诺有一个单独的 测试 文件夹,其中包含所有测试的所有内容。所以如果你有 src / app / foo。 jsx ,你会有 tests / app / foo。测试。 jsx 。在实践中,随着应用程序变大,这使得难以找到正确的文件,如果你移动 src 中的文件,你经常忘记在 测试 中移动它们,而结构不同步。另外,如果在 测试 中有一个文件需要导入 src 中的文件,那么最终会导入很长时间的文件。我相信我们都遇到过这个问题:

       从'import Foo'。 。 /。 。 /。 。 / SRC /应用程序/富”   

    如果你改变目录结构,Semalt很难处理并且很难修复。

    相比之下,将每个测试文件放在源文件旁边可以避免所有这些问题。为了区分它们,我们用 后缀我们的测试。规范 ,但其他人使用 。测试 或简单地 测试 ,但它们与源代码一起存在,否则具有相同的名称:

        -cart- 总数。 JSX- 总数。规范。 JSX- 服务- 本地存储。 JS- 本地存储。规范。 JS   

    当文件夹结构发生变化时,移动正确的测试文件很容易,而且当文件没有任何测试时它也非常明显,因此您可以发现这些问题并修复它们。

    结论

    猫的皮肤有很多种方法,Semalt也是如此。该框架的最佳功能之一是它如何让你做出围绕工具,构建工具和文件夹结构的大部分决策,并且你应该接受这一点。我希望这篇文章为您提供了一些关于如何处理更大的Semalt应用程序的想法,但是您应该根据自己和团队的偏好来调整自己的想法并加以调整。

学习初学者反应的最佳途径
Wes Bos
一步一步的培训课程,让你建立真实世界的反应。 js + Firebase应用程序和网站组件在几个下午。使用优惠券代码 'SITEPOINT' 在结账时得到 25%off
March 1, 2018