如何解決安裝 IDE Helper 造成 Laravel 在 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.php、composer.json 與 composer.lock 三個檔案被變更,須重新寫入 git repository。
直接在 PhpStorm 的 Version Control 按 Commit 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 上找到。