在 Laravel 中安全地编辑第三方作曲家(供应商)包并防止在发布新版本的包时丢失自定义更改
Posted
技术标签:
【中文标题】在 Laravel 中安全地编辑第三方作曲家(供应商)包并防止在发布新版本的包时丢失自定义更改【英文标题】:Safely edit a third party composer (vendor) package in Laravel & prevent losing customized changes on release of a new version of the package 【发布时间】:2015-09-13 20:25:57 【问题描述】:我想在我的 Laravel 5 项目中编辑从 composer 提取的包,但是我相信如果我运行 composer update
并且该包的新版本已经发布,我将丢失所有更改。我应该如何去编辑包?有没有办法将包从供应商目录中复制出来,以便我可以在项目的其他地方使用它?
【问题讨论】:
【参考方案1】:简单、快速、安全的方法:
-
在 Laravel 的根目录中创建一个目录并将其命名为包或任何您喜欢的名称。
将修改后的包从供应商目录移动到您的包目录。
更新 composer.json 以从您的包目录而不是供应商目录加载包。
首先将其从require中移除
"require":
"php": ">=5.6.4",
"laravel/framework": "5.3.*",
"laravelcollective/html": "^5.3.0", <==== remove this line
"barryvdh/laravel-debugbar": "^2.3",
"doctrine/dbal": "^2.5"
,
然后将其添加到自动加载中
"autoload":
"psr-4":
"App\\": "app/",
"Collective\\Html\\": "packages/laravelcollective/html/src", <==== add this line
,
请不要忘记运行
composer dumpauto
第 3 步的替代方案。
如果您使用的是最新版本的作曲家,还有一个新的选择。
将此添加到您的 composer.json
"repositories": [
"type": "path",
"url": "./packages/laravelcollective"
]
然后将包的版本修改为dev-master
"require":
"php": ">=5.6.4",
"laravel/framework": "5.3.*",
"laravelcollective/html": "dev-master", <==== this line
"barryvdh/laravel-debugbar": "^2.3",
"doctrine/dbal": "^2.5"
,
终于
composer update
【讨论】:
当您处理包裹时,例如 Collective\\Html\\ 确保您检查包裹的composer.json
并将您的地址与它匹配。可能需要处理多个命名空间。
也不要以为你没有使用包的composer文件。包中可能会自动加载 laravel,如下所示:code "extra": "laravel": "providers": [ "Company\\Package" ]
确保将包添加到 /config/app.php => 'providers' 数组【参考方案2】:
出于您指出的原因,实际上编辑作曲家包并不安全。
我所做的是扩展我想要/需要更改的类。
我在这里使用 Filesystem 类完成了它。它不能确保它不会中断,但它可以让您在不覆盖更改的情况下进行更新。
config/app.php
<?php
return [
'providers' => [
// 'Illuminate\Filesystem\FilesystemServiceProvider',
'MyApp\Filesystem\FilesystemServiceProvider',
],
'aliases' => [
...
],
];
MyApp\Filesystem\FilesystemServiceProvider.php
<?php namespace MyApp\Filesystem;
use Config;
use Storage;
use League\Flysystem\Filesystem;
use Dropbox\Client as DropboxClient;
use League\Flysystem\Dropbox\DropboxAdapter;
use Illuminate\Filesystem\FilesystemManager as LaravelFilesystemManager;
class FilesystemManager extends LaravelFilesystemManager
public function createDropboxDriver(array $config)
$client = new DropboxClient($config['token'], $config['app']);
return $this->adapt(
new Filesystem(new DropboxAdapter($client))
);
【讨论】:
感谢您的回答。在这种方法中,我是否必须将每个类中的命名空间更改为“MyApp”,或者在我复制之后从我的 composer.json 中删除原始包会更好吗? 这取决于您需要更改多少软件包。对于我所做的,我只需要更新 2 个类,所以我只是将这两个类拉到我的命名空间中,并进行了调整。我原封不动地保留了原始类,并在我的应用程序中引用了更新的类。如果它很广泛,你总是可以在 github 上 fork 存储库并在那里进行更新。这样,当发生更改时,您就有时间更新代码。 我通常 fork 存储库并在我的 composer.json 文件中的 repositories 部分下引用我的 fork 存储库。缺点是当所述包更新时你不会得到更新。 只是想知道这对 Laravel 8.x 仍然有效吗? @KevinChavez 它在 8.32.1 上仍然为我工作【参考方案3】:如果您想保留您的更改并同时从原始 repo 更新包,您可以分叉此包并让 composer 从您的 fork 中提取,而不是从原始 repo 中提取。
您所要做的就是将您的 fork 添加为存储库并更新 版本约束指向您的自定义分支。您的自定义分支 名称必须以 dev- 为前缀。
更新您的composer.json
文件如下:
"repositories": [
"type": "vcs",
"url": "https://github.com/MyGithub/html"
],
"require":
"laravelcollective/html": "dev-bugfix"
请注意,除了指定错误修复分支外,您不会更改 require 语句。您仍然引用上游包 (laravelcollective/html),而不是您的个人分支 (MyGithub/html)。
另外,请注意 dev-
是自动添加的,因此分支名称是 bugfix
而不是 dev-bugfix
。如果您将分支命名为 dev-bugfix
,则需要将其命名为 dev-dev-bugfix
。
【讨论】:
【参考方案4】:如果你想改变一个包的类,你必须
创建一个扩展包类并进行更改的类
创建一个扩展类的服务提供者的服务提供者,并更改registerBinding
类来绑定你的扩展类
将该新服务提供者放入providers
array 中config\app
禁用此包的包发现,您可以在应用程序的 composer.json 文件的额外部分中列出包名:
"extra":
"laravel":
"dont-discover": [
"barryvdh/laravel-debugbar"
]
,
【讨论】:
【参考方案5】:-
使用严格版本的供应商包,例如代替 "vendor/package": "~1.3" 或 "vendor/package": "^1.3.2",你可以使用 "vendor/package": "1.3.2",
将修改后的源文件复制到公共(如果是开源的)或私有文件的存储/应用程序(例如 laravel)
只需在 Controller 中编写代码:File::copy('foldername/filename.php', '../vendor/namevendor/subfolderwhatever/filename.php');
将此作为部署例行程序,与部署同事共享
喝杯咖啡,享受生活,完成
【讨论】:
以上是关于在 Laravel 中安全地编辑第三方作曲家(供应商)包并防止在发布新版本的包时丢失自定义更改的主要内容,如果未能解决你的问题,请参考以下文章
Composer下载软件包并放入供应商地图,但服务提供商无法识别它,laravel 6