將部落格的 Laravel 版本從 7 升級至 8,當中所遇到的問題

程式技術 sharkHead 7個月前 0

繼上次 7 月底將部落格從 6 升級 7 之後,Laravel 8 隨後在 2020 年 9 月 8 日正式發布
這次升級一樣沒有遇到什麼的問題,但是 Laravel 8 有許多重大的革新
升級時務必仔細閱讀官方文件的升級手冊

總之,來說說這次將部落格從 7 升級至 8 的心得吧

 

路由寫法更改


首先是路由寫法的變更,以前的寫法是這個樣子的

Route::get('/', 'HomeController@index')->name('home');

現在則要改成

use App\Http\Controllers\HomeController;

// 首頁
Route::get('/', [HomeController::class, 'index'])->name('home');

下方的寫法其實在 8 發布之前,就有人提倡應該這樣寫
個人認為這樣的寫法比較直觀,也比較優雅,Laravel China 中有網友討論路由的更改,可以參考

 

Factory 寫法更改


Laravel 8 把 Factory 重寫為基於類的寫法,這個寫法不兼容 7 之前的寫法
雖然官方有出一個套件 laravel/legacy-factories 可以讓 8 兼容舊版的寫法
不過遲早都要改,不如一開始就改

首先舊版的寫法是

use Faker\Generator as Faker;
use Illuminate\Support\Str;

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

新版的寫法,將 Factory 包成一個類來使用

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class UserFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = User::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}

如果在 seeder 中想要使用模型的 Factory,例如

$users = User::factory()->times(10)->make();

那麼就要先設定好 Model 的 Factory
然後在 Model 中寫上一行 use HasFactory

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasFactory;
}

 

預設 CSS 框架更改


Laravel 的 CSS 框架原本是使用 Bootstrap,在 8 之後,Laravel 的作者決定更改成 Tailwind CSS
Tailwind CSS 是近期興起的 CSS 框架,特點是將常用的 CSS 屬性包成一個又一個的 class name
讓使用者可以直接在標籤的 class 屬性中設定樣式,因此直接重新整理網頁就能看出調整樣式的效果
不會有因為被瀏覽器快取而看不到變化的問題

擷取一段官網的範例

<div class="max-w-sm rounded overflow-hidden shadow-lg">
  <img class="w-full" src="/img/card-top.jpg" alt="Sunset in the mountains">
  <div class="px-6 py-4">
    <div class="font-bold text-xl mb-2">The Coldest Sunset</div>
    <p class="text-gray-700 text-base">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
    </p>
  </div>
  <div class="px-6 pt-4 pb-2">
    <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#photography</span>
    <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#travel</span>
    <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#winter</span>
  </div>
</div>

你可能發現標籤中的 class 屬性都變得很長
如果網站要設計成 RWD(響應式網頁設計),那麼你看到 class 屬性可能還會變得更長
你可能會覺得這樣 Code 好像變醜了
但是所有標籤的樣式你都可以一目瞭然,減少 CSS overwrite 的情況
此外,Tailwind CSS 可客製化程度非常高
你可以自己定義 class name,也可以將許多 class name 包成一個 class name 來使用
甚至還能用 purgeCSS,將沒用到 class name 去除,讓 CSS 檔案大幅瘦身,加快網頁讀取的速度

Laravel 中好用的分頁(Pagination)功能,也從 Bootstrap 改成使用 Tailwind CSS
所以如果你的網頁是從 7 之前升級上來,並且有使用 Bootstrap的話
你會發現分頁選單會直接大跑版,Laravel China 一樣有網友遇到這個情況

如果你想要讓分頁使用 Bootstrap 的話(實在是懶得改)
需要在 app/Providers/AppServiceProvider.php 的 boot() 中加入一行 Paginator::useBootstrap();

use Illuminate\Pagination\Paginator;

public function boot(){
	Paginator::useBootstrap();
}

可以參考文件的說明 

 

Laravel Jetstream 新登場


這一 Part 其實跟我的部落格升級沒有關係,因為我並沒有升級這部分 (`・ω・´)
但也是 Laravel 8 重點更新的項目,小弟稍微研究了之後,感覺之後部落格很有機會會用到,所以稍微介紹一下

想必很多人 Laravel 中想要實作會員功能時都會使用 Laravel UI 這個套件
這個套件可以快速地建立一個基本會員系統,包含登入、登出與註冊
如此好用的套件,在 Laravel 8 正式宣告將被 Jetstream 取代了 !

giphy.gif
哪泥!?

先說說什麼是 Jetstream,其實就是加強版本的 Laravel UI
除了基本的會員系統,Jetstream 擁有更多功能,像是

  • 雙因素認證
  • API Token 管理
  • Teams 團隊管理,可以將會員加入、移出或是切換團隊

至於前端的部分,你可以選擇

這邊你可能會想問,Inertia.js 跟 Livewire 是什麼東西?

一般來說,如果我們使用 Laravel 搭配 Vue.js 的來做專案的話
基本上就不會用到 Laravel 的 Router,而是使用 Vue.js 的 Vue Router,前端會使用 Call API 的方式去跟後端拿取資料
而 Inertia.js 的功用,就是讓你可以繼續使用 Laravel 的 Router 去跟前端做資料串接
詳細可以參考 IThome 主辦的鐵人賽系列文章,關於我用 Laravel 寫 SPA 卻不寫 API 的那檔事

而 Livewire 功能是可以在不整理網頁的情況下,與後端拿資料
等等,這不就是 AJAX 嗎?沒錯,目的大致上是一樣的
只是一般寫 AJAX 需要注意的資安問題,Livewire 都已經提前幫你解決了
Livewire 官方有一系列教學影片,可以參考

 

總結


其他還有許多零零總總的更新,這裡就不一一贅述了
除了跟著升級文件走,還需要去 Laravel 的 Github 中查看還有哪邊需要更動
盡可能的將專案與最新版本的 Laravel 保持一致
當然只要重新開一個 Laravel 8 專案,重新寫就沒有這個問題了

 

八卦


Jetstream 一推出在社群引起廣大的討論,其中也包含不小的反彈聲浪

主要是因為預設的 Tailwind CSS,雖然高度可客製,但是學習成本明顯比 Bootstrap 要來得高
而社群中也有人質疑 livewire 與 inertia 的技術成熟度

因此作者特地在 Youtube 頻道中上傳了長達一個小時的影片
解釋為什麼要將前端框架從 Bootstrap 改成 TailwindCSS,還有推出 Jetstream


Laravel 與 Python 菜雞工程師
喜愛研究程式相關技術
正在學習 TypeScript 與 Vue.js