使用ember-cli的多个“应用程序”

时间:2014-07-09 19:10:38

标签: ember.js ember-cli

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

我正在试图弄清楚是否可以使用ember-cli,如果是这样,我该怎么做?我看到有人谈论豆荚,其他人谈论插件和另一组人谈论私人凉亭回购。我试图找出有关这些信息的信息,但似乎有点变化。

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

[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日):

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

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

2 个答案:

答案 0 :(得分:3)

Ember-cli不支持开箱即用的多个应用程序。 (顺便说一下,我仍然惊讶于SproutCore中常见的很多事情仍然存在问题)。您提到的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)。

答案 1 :(得分: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 - 它会产生更高质量的microlib。 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应用程序可称为微服务方法。)

  4. 超级项目

    组织

    您可以探索Git 子模块(* shudder *)子树或NPM工件。你会跳过箍,让它们保持同步。

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

    服务

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

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

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

    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))