导入深度嵌套的 Javascript 组件的最佳实践

Posted

技术标签:

【中文标题】导入深度嵌套的 Javascript 组件的最佳实践【英文标题】:Best practices for importing deeply nested Javascript components 【发布时间】:2016-02-26 09:14:26 【问题描述】:

我正在开发一个 Ruby/React 项目。我们使用 React 组件和 CoffeeScript,最终的 JS 由 Sprockets 组装:

#= require org/components/whatever

 Whatever  = Org.Components

没有太多嵌套也没关系,然后你会写这样的东西:

#= require org/components/whatever
#= require org/components/something/else/whatever

 Whatever1  = Org.Components
 Whatever2  = Org.Components.Something.Else

今天我试图找到Org.Components.Image.Upload 的使用位置。但有时它被导入为 Upload 或用作Image.Upload 并没有让事情变得更容易。

现在我在想也许不要比Org.Components 更进一步进口。因此,如果您需要 Image.Upload — 获取 Image = Org.Components,然后使用 Image.Upload。如果它变得太长 - 分配给一个变量。

#= require org/components/image

Image = Org.Components
Upload = Image.Super.Complex.Upload

# Or use it like this for explicitness
render: ->
  Image.Super.Complex.Upload 

这里的最佳做法是什么?我希望代码是可搜索的。

【问题讨论】:

对对象的本地引用可以帮助减少查找时间,这似乎是您正在做的事情,但是如果它是有组织的,依赖声明模式会非常有用并且方便。 我通常在处理深度嵌套的对象时使用该方法。 我认为没有最佳实践。但是你当然不应该混合它们,使用 either 解构 变量赋值。 另一种选择:Components: Image = Org; 问题是 - 这是不可搜索的。我希望能够知道组件在哪里使用,以便于重构。 【参考方案1】:

如果您在 CommonJS 环境(节点)中,并且可能使用像 Webpack 或 Browserify 这样的模块捆绑器,您可以利用直接模块导入。例如:

您可以这样做,而不是这样做Org.Components.Image

import Upload from 'org/components/Image/Super/Complex/Upload'
// or var Image = require('org/components/Image/Super/Complex/Upload');

在您的原始策略中,您加载整个库 (org) 以进一步将其过滤到 Upload

在上面建议的解决方案中,您只加载 Image 模块而不加载其他任何内容。这可能会在您的最终占用空间中节省大量代码,特别是如果 org 包含您公司内部使用的大量组件。

【讨论】:

问题是如果我单独重用 Image.Upload 会怎样 对不起,如果我把你的问题弄错了。但我要说明的一点是始终只引用您在给定依赖项中寻找的模块。在您的场景中,我想说最好的做法是始终为 Upload 组件设置整个路径。希望我在这里有点道理。【参考方案2】:

为了停止与 sprocket 对抗,我定义了一个 Root 组件,它告诉 Sprocket 在哪里寻找子组件:

# components/branding.coffee

 #= require_tree ./branding

Org.Components.Branding = 

所以现在,如果我需要品牌子树中的任何内容,我只需执行以下操作:

#= require org/components/branding

div = React.DOM

Branding = Org.Components

Org.defineComponent "Settings.Branding",
  render: ->
    div ,
      Branding.Edit.ContactUs 
      Branding.Config ,
        Branding.Edit

这样我就不必担心依赖关系,并且发现使用起来更加愉快。

我建议这种方法有助于重构,因为您不必到处更改多个需求。

Branding.Config 是一个数据包装,用于加载和同步设置。在上面的示例中,它用于加载Brading.Edit 页面的设置。在这里,它正在为“Layouts.Default”加载品牌。

我只需要branding

# apps/src/org/components/layouts/default.coffee

#= require org/components/branding

Branding, TenantStateBar, UnsupportedBrowserBar = Org.Components

Org.defineComponent 'Layouts.Default',
  render: ->
    div ,
      Branding.Config ,
        Branding.Style

【讨论】:

以上是关于导入深度嵌套的 Javascript 组件的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

测试嵌套 JavaScript 对象键是不是存在

测试嵌套 JavaScript 对象键是不是存在

打破 JavaScript 中嵌套循环的最佳方法是啥?

从嵌套的 javascript 对象中删除属性的最佳方法是啥?

Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信

深度嵌套的 flexbox 布局会导致性能问题吗?