草庐IT

php - 带有 Composer 的多个应用程序

coder 2024-04-21 原文

有一个主应用,我们称它为APP。

APP有几个依赖项(包括开源项目和专有库)。

有多个客户端使用他们自己的 APP 实例(在我管理的不同域上)。其中一些客户端使用的APP版本略有调整。我通过为每个客户端创建一个特定模块(让我们称之为 SM)来实现这一点,我只是将其添加到他们的 APP 实例中(这样我就不会更改 APP 中的任何代码)。

目前,我已经实现如下:

  • 本地开发APP,使用Composer更新其依赖(composer update),pushAPP到central repo

  • 对于每个常规客户端,从中央仓库拉取 APP 并安装 Composer 依赖项(composer install)

  • 对于具有特定实现的客户端,创建一个新的 SM(特定模块),它具有以下 composer.json 文件:

    ...
    "require": {
        "APP": "X.X.X"
    } 
    ...
    

然后对这个 SM 应用与之前相同的步骤(composer update 在本地,PUSH 到中央 repo,PULL 从中央 repo,composer install).

一切都很好,除了我想克服的两个问题:

    来自 APP 的
  1. composer.lock 将被 SM 忽略(因为 APP 作为库加载到 vendor/ 文件夹中,而 composer 忽略 composer.lock 库文件);这一点都不好,因为我不确定特定客户端是否会使用与 APP 完全相同的库。

  2. 每次我在 APP 中修复错误或实现新功能时(这种情况经常发生 - 一天几次),除了我为普通客户执行的步骤外,我还需要重建SM(因为他们的一个库 - APP - 已更新到我需要使用的新版本)。这是一项开销,因为我执行的大部分更改都在 APP(而不是 SM)内。所以,如果是另一种方式(APP 将 SM 作为依赖项),它会工作得更快(因为我不需要在每个 SM 上composer update)。

是否有任何已知的工作流或最佳实践涵盖此场景以缓解上述两个问题或至少降低升级/部署过程的复杂性?

请注意,上面的大部分步骤已经自动化,所以我的问题不是关于自动化部分,而是这个架构的复杂性

最佳答案

I implemented this by creating a specific module (let's call it SM) for each client that I just add to their instance of APP

For clients with specific implementation, create a new SM (specific module), that has the following composer.json file:

它是一个具有客户端特定模块(与其他依赖项相邻)的应用程序。

应用程序具有模块作为依赖项(APP具有SM作为依赖项)。

并且不是:模块拉取应用程序,因为它是供应商依赖项。 这只会导致在开发阶段(您的问题 2)采取额外的步骤。

我建议重构应用程序及其模块,直到您获得以下文件夹结构:

|-application             #< the application has dependencies
  |-src
  |-tests
  |-vendor
    |-framework           #< maybe your application is framework based
    |-libs                #< more dependencies
    |-...                 #< other modules
    |-sm                  #< the client specific module

这允许引入依赖项,从而扩展“应用程序”以满足客户特定的需求。

这解决了问题 1,因为 APP 是主存储库并包含锁定文件。必须锁定版本,以便所有开发人员都绑定(bind)到相同的版本,并且打包完全相同的版本集。

So, if it was the other way (APP having SM as a dependency), it would have been working faster (since I wouldn't need to composer update on each SM).

是的!如果您开始使用模块依赖项“在 APP 内部开发”,则每次更改 APP 时都不需要重建模块。


对于多个客户端,只需使用具有一组自定义要求的多个应用程序存储库即可。 10 个客户端,10 个应用程序存储库,10 个 composer.json 文件。运行 composer install no-dev 然后预先打包每个 repo 并将 zip 放入下载。完成。

您可以在此处使用“容器”或“打包”项目,其中每个项目的 composer.json 将包含应用程序和特定模块。您可以使用插入符或波浪号运算符来指定应用程序的版本范围("vendor/app": "^1.2.3"),然后简单地updaterepackage,在应用程序的新版本发布后。这种方法应该适用于 composer 自动加载,因为应用程序也将保留在 vendor 文件夹中。只需要一个小包装器,即可设置 composer 自动加载器并切换到您的应用程序。

或者,如果应用程序真的是模块化的。只需打包主应用程序并提供特定于客户端的模块作为额外下载。使用这种方法升级将有多个下载步骤:升级应用程序、升级模块。将其视为“wordpress 风格”更新/升级。


您可以通过删除客户端计算机上的 composer install --no-dev 部分来进一步降低升级/部署过程的复杂性 通过在开发人员机器上构建“特定于客户的应用程序文件”。 这些基本上是应用程序的“--no-dev”包及其所有依赖项,包括客户端特定模块 = 预打包。

例如,Application-v1.2.3-WithModuleAForClientA-v3.2.1.zip

在开发机器上:composer install --no-dev --optimize-autoloader + zip

安装或升级只需下载到客户端,解压,执行升级脚本。完成。

关于php - 带有 Composer 的多个应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30230925/

有关php - 带有 Composer 的多个应用程序的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  3. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  4. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  5. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  8. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  9. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  10. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

随机推荐