將 IDE Helper 安裝在 require-dev 將造成 Azure 部署失敗

Laravel IDE Helper 解決了 PhpStorm 無法對 Facade 做 code completion 的問題,,為使用 Laravel 與 PhpStorm 必裝的套件,但安裝方式的差異,可能造成 Laravel 在 Azure 無法部署成功。

Motivation


因為 IDE Helper 為開發用套件,在如何在 PhpStorm 活用 PHPDoc? 一文中,建議大家將 IDE Helper 安裝在 require-dev,事實上開發用套件都應該使用這種方式安裝,不過 IDE Helper 在 Azure 部署時卻遇到困難。

Version


PHP 7.0.8
Laravel 5.2.41
PhpStorm 2016.2

實際案例


已經在本機順利安裝 IDE Helper 的 Laravel 專案,部署到 Azure 後,出現部署失敗的錯誤。

Settings -> Publishing -> Development source

部署出現 Failed

繼續往下按 View Log,按錯誤訊息。

錯誤訊息出現在 composer install 之後,在執行 php artisan optimize 時,出現找不到 Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider 的錯誤。

Root Cause


觀察 composer.json,會發現當 Azure 在執行完 composer install 後,會觸發 post-install-cmd 事件,並執行 php artisan optimize

一旦執行 php artisan optimize,就會執行 config/app.php 的所有 service provider,當然包括我們安裝 IDE Helper 新增的 Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider

實際由 PhpStorm 的 Remote Host 連到 Azure,會發現 Laravel 專案只出現在 repository 目錄下,而沒在 wwwroot 目錄下,事實上 Laravel 整個專案應該放在 wwwroot 目錄下,這表示在 Azure 的部署並沒有成功。

我們再比較本機的 vendor 目錄與 Azure 的 repository 下的 vendor 目錄,會發現 Azure 的 vendor 目錄並沒有 IDE Helper 所需的 barryvdh 目錄。

Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider 這個 service provider 正是放在 vendor/barryvdh 目錄下。

打開本機的 composer.json,我們發現 barryvdh/laravel-ide-helper 是放在 require-dev,也就是說,Azure 在部署時,是下 composer install --no-dev,因此才沒將 barryvdh 安裝在 vendor 目錄下。

Solution


composer.json 中,將 barryvdh/laravel-ide-helper": "^2.2"require-dev 改到 require

雖然本機已經有 vendor/barryvdh,但別忘了 composer install 吃的是 composer.lock,所以我們必須重新執行 composer update 來更新 composer.lock

composer update 執行完後,會發現 _ide_helper.phpcomposer.jsoncomposer.lock 三個檔案被變更,須重新寫入 git repository。

直接在 PhpStorm 的 Version ControlCommit Changes 即可。

輸入 commit message 之後,直接按 Commit and Push 一併 push 到 GitHub。

Push 直接送進 GitHub。

上傳至 GitHub 成功。

再次觀察 Azure 的部署訊息,這次就成功了。

由 PhpStorm 的 Remote Host 去觀察 Azure,wwwroot 目錄下的確有完整的 Laravel 專案,表示 Azure 已經成功部署。

再觀察 vendor 目錄的確多了 barryvdh,因此 php artisan optimize 時,可以順利找到 Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider

Conclusion


  • Azure 會自動下 composer install --no-dev,因此只會安裝 require 的套件,不會安裝 requre-dev 的套件。
  • 開發用的套件,理論上安裝在 require-dev 即可,除非該套件會用到 service provider,就必須改安裝在 require,否則會造成 Azure 部署失敗。

Sample Code


完整的範例可以在我的 GitHub 上找到。