【问题标题】:Multiple "apps" with ember-cli带有 ember-cli 的多个“应用程序”
【发布时间】:2014-08-30 23:10:20
【问题描述】:

我正在尝试从一些旧的本土构建工具迁移到 ember-cli。我们的应用程序非常大,实际上被拆分为几个共享一组通用工具和组件的 ember.js 单页应用程序(例如索引、管理、报告等)。

我试图弄清楚 ember-cli 是否可以做到这一点,如果可以,我该怎么做?我看到一些人在谈论 Pod,其他人在谈论插件,还有一些人在谈论私人凉亭回购。我试着找出每一个的信息,但似乎一切都在变化。

我对目录结构或细节并不挑剔。但我想这就是我的设想:

[app]
  - [controllers]
  - [models]
  - [routes]
  - [views]
  - index.html
[admin]
  - [controllers]
  - [models]
  - [routes]
  - [views]
  - index.html
[reports]
  - [controllers]
  - [models]
  - [routes]
  - [views]
  - index.html
[shared_code]
  - [components]
  - [utils]
Brocfile.js
etc

任何建议将不胜感激。即使只是一个起点也会非常有帮助。


编辑(2015 年 1 月 28 日):

Ember-cli 插件现在更加稳定,可用于此应用程序。但是恕我直言,他们对于这个用例仍有一些不足之处。它们创建了更多样板,因为您仍然必须将单个模型/控制器/组件/等导入您的应用程序空间。请参阅此处插件下的“组件”部分:http://www.ember-cli.com/#managing-addon-dependencies

还有一个有趣的 RFC 为 ember 和 ember-cli 带来类似引擎的支持,也可以满足这一点:https://github.com/emberjs/rfcs/pull/10


编辑(2015 年 10 月 3 日):

引擎 RFC 有一个新的更新,这对许多用户来说看起来很有希望。但是,我们仍然需要多个实际上不同的应用程序。与我一起工作的另一位开发人员花了一些时间详细介绍了如何最好地使用此模式。

我已经记录并在回购中创建了演示:https://github.com/workmanw/ember-multi-app

【问题讨论】:

  • 那么韦斯利,你最后决定做什么,因为我现在也在考虑这个问题 (discuss.emberjs.com/t/sharing-models-via-ember-cli-addons/6311/…)
  • @cjroebuck 我看到了你的讨论帖,这正是我想要做的。起初,我可以在 Brocfile.js 中使用我的公共文件创建两个 EmberApp 实例和第三棵树,然后使用合并树让它们全部工作。但是目前 ember-cli 的波动性在现在看来太大了。所以我用了纯西兰花。我希望在它更稳定后重新使用 ember-cli 解决方案。
  • @cjroebuck 另外,我认为显然需要这种行为。希望将来它会成为 ember-cli 的一个简单功能。
  • 我现在走的是 ember-addon 路线,所以我所有的公共代码都在“common”项目中,这是我使用 npm 添加到我的两个应用程序的 ember 插件dev 中的链接 - 到目前为止还不错,但我同意 ember-cli 正式支持此工作流程作为实际用例会很好。

标签: ember.js ember-cli


【解决方案1】:

如果您必须使用 Ember CLI 完成多个应用程序,根据您在 2015 年 1 月 28 日的编辑,您需要等待更多的 pod 支持或引擎。

但请考虑这里的简单 DIY 解决方案:将您的 n 单独的 Ember 应用程序转换为 n 单独的 Ember CLI 应用程序。在一个超级项目中亲自为他们服务。

缺点

与您对插件的调查一样,您将有重复的样板文件,package.jsonenvironment.js 等。您将承担单独维护每个应用的 Ember、Ember CLI 等版本的开销。您必须自己创建一种方式来在一个超级项目中为他们提供服务。即使多个应用在同一个库版本上,客户端也可能不得不下载重复的 vendor.js 代码。

这些都是你必须权衡的严重缺点。

优势

  1. 您保留当前的代码组织。

  2. 您必须遵守所提取的共享代码。

    “复制比错误的抽象要便宜得多。”在动态 JavaScript 的世界里,任何东西都在类型系统中,每个人都有不同的模块实现,过早抽象/提取会给你带来麻烦。当共享代码被小心地提取到一个单独的库中时——可能使用the Rule of 3——它会产生更高质量的微库。 lib 的维护可以集中在优化共享功能及其向后兼容性上。如果共享代码保留在您的应用程序中,通过 import spaghetti 使用,您可能无法理解。

    frzng's answer 一样,“包括通过 Bower、NPM 和 Ember 插件共享的代码”。

  3. 一个应用程序的技术债务不会破坏另一个应用程序。

    这在 Ember 生态系统中尤其有用。尽管它的座右铭是“稳定而不停滞”,但每天都会出现新的 Ember 图案。想尝试其中一种最前沿的 Ember 技术,但又不想花时间升级整个 Ember 单体?只需升级一个较小的应用程序!

    我曾与大型 Ember 应用合作过,该应用在小范围内的技术债务无法升级整个应用。有了这个方案,就不用说不了。

    Halting the spread of tech debt is part of why microservices are so popular lately.许多小型 Ember 应用程序可以称为微服务方法。)

超级项目

组织

您可以探索 Git 子模块 (*shudder*) 子树或 NPM 工件。您将跳过障碍以使它们保持同步。

在我的情况下,运行 1 个应用程序而没有其他应用程序是没有意义的。我通过monorepo 取得了成功。

服务

我的 URL 方案适用于我的 Ember 应用程序的类 Unix 哲学分离。每个都可以由单个服务器提供服务,但每个都分组在逻辑上独立的上下文路径下。例如,对/app1/* 的所有请求都被路由到应用#1 的已编译index.html。所有对/app2/* 的请求都被路由到应用#2 的编译后的index.html。等等。 Ember 从那里接管路由。

您也许可以对/index/*/admin/*/reports/* 执行相同的操作。

要将这些应用程序挂载到它们的各种公共 URL,请在每个应用程序的 package.json 中添加一些元数据,以告诉服务器如何操作。启动时,服务器循环遍历元数据,并动态生成 W​​eb 框架路由。

for packageJson in packageJsons:
    path = packageJson.contextPath                               # e.g. '/app1/*'
    indexHtml = packageJson.abspath.dirname + '/dist/index.html' # Ember CLI's conventional location

    # Dynamically mount the route.
    # Normally you'd hardcode your routes, something like  
    #     yourWebFramework.GET('/hello', echo('Hello world'))
    yourWebFramework.GET(path + '/*', serveStaticFile(indexHtml))

【讨论】:

    【解决方案2】:

    Ember-cli 不支持开箱即用的多个应用程序。 (顺便说一句,我仍然很惊讶在 SproutCore 中常见的许多事情在 Ember 中仍然存在问题)。您提到的pods 由 ember-cli 依赖的工具支持,因此大多数 ember-cli 命令都可以正常工作。解析器(一种 ember-cli 依赖项)将所有内容放在一起的方式在 its pull request 中进行了描述。但是您将无法使用生成器,因为它们还不知道 pod。 Ember 插件大多扩展了 ember-cli 或 Ember 本身,虽然它们可能能够解决您的问题,但它们不是正确的工具。

    我认为对你来说最好的事情是等待更多的 pod 感知 ember-cli 命令,或者自己实现这个特性来 ember-cli。

    接下来最好的做法是将您的项目实际拆分为多个项目,每个应用一个,并通过 Bower、NPM 或其他解决方案包含共享代码。如果您有自己的私有组件,它们通常都允许通过 git 或文件系统导入依赖项。您可能有一个超级项目,其中所有内容都在一起(通过 NPM 或 Git submodules),并且您仍然有一些本土解决方案来协调所有内容(基本上将其委托给 ember-cli)。

    【讨论】:

    • ember-cli 插件是新的,是跨项目共享原始代码的好方法。值得一试。
    • @SamSelikoff 我同意,我只是不认为它们适用于应用程序。它们非常适合在众多应用程序之间共享代码,更通用。
    • 当然,不适用于应用程序。但是,如果他采用您建议的方法,将它们分成不同的应用程序,但又想共享一些代码,他们可以使用插件。
    • 抱歉来晚了。我确实尝试使用带有npm link 的插件,但它们不符合需要,感觉就像我在逆流而上。首先,它们是“无人关注的”,更改插件代码不会触发应用程序重建。其次,它们最终被夹在应用程序解析路径下。所以“my-addon/controllers/alpha”变成了“app/controllers/alpha”......可能会导致冲突。最后,我无法模拟生产。 prod 中的“/”、“/admin”、“/report”分别变成:“localhost:4200/”、“localhost:5200/admin”和“/localhost:6200/report”。
    • 说了这么多^^,感谢您的回复。至少我能够承认我并不孤单。我也是一个“老 SproutCore 家伙”。肯定有一些事情我偶然发现并闪回 SC 是如何处理它的。但总而言之,使用路由器、模板、承诺、解析器等;我仍然会在一周中的每一天都接管 EM,而不是 SC。
    猜你喜欢
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多