自分のポートフォリオで使用しているVue,jsをver.2→ver.3にアップデートしたお話

こんにちはー、ニアです!

自分のポートフォリオはフレームワークにVue.jsを使っているのですが、先日にポートフォリオの更新のついでに、Vue.jsのバージョンを2(以下、Vue 2)から3(以下、Vue 3)にアップデートしました。

1. Vue 2はサポート終了済み! Vue 3にアプデする? それともReact?

Vue 2は、2023年末にサポートが終了していたので、セキュリティの観点からアップデートなどの対応が必要でした。

業務では、フロントエンドの開発で主にReactやNext.jsを使っているので、プログラミングの復習も兼ねてReactにする案もありましたが、別の案件でVue.jsを使うことになった時に取り掛かりやすいように、自分のポートフォリオではVue.jsを引き続き使い、Vue 3にアップデートすることにしました。

ついでにビルドツールもVue CLIからViteに変更しました。もちろん、Vercelでのビルド&デプロイに利用できます。

Vite on Vercel
Learn how to use Vercel's features with Vite.
Nia-TN-SDfs-wink.png
Vue CLIと比べてビルドが高速らしいです。
自分のポートフォリオでも、高速化を体感できました

2. Let’s Vue 3にアップデート

Vue 3へのアップデートとViteへの変更は、以下のように作業をしました。

  1. Vue.jsなどのライブラリをアップデート、Viteをインストール
  2. Viteのコマンドラインツールで、新しいVue.jsのプロジェクトを作成
  3. Viteでのビルド必要なファイルを、ポートフォリオのプロジェクトにコピー
  4. コンポーネントなどのソースコードをVue 3用に修正

2.1. Vue 3では、Composition APIを使って、コンポーネントを記述

Vue 2の頃は、Vue Class ComponentとVue Property Decoratorを使って、コンポーネントを記述していました。

<template>
    <tr>
        <td>{{ name }}</td>
        <td>{{ skillGradeStar }}</td>
    </tr>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

export interface SkillItem {
    name: string;
    skillGrade: number;
}

@Component
export default class SkillListItem extends Vue {
    @Prop()
    private name!: string;

    @Prop()
    private skillGrade!: number;

    get skillGradeStar() {
        let adjustSkillGrade = Math.min( 5, Math.max( 1, this.skillGrade ) );
        return "★".repeat( adjustSkillGrade ) + "☆".repeat( 5 - adjustSkillGrade );
    }
}

</script>

Vue 3では、Composition APIを使って記述し、プロパティは defineProps() で定義し、getterの部分は、computed() で定義しました。

<script setup lang="ts">
import {computed} from "vue";

export interface SkillItem {
  name: string
  skillGrade: number
}

const props = defineProps<SkillItem>();

const skillGradeStar = computed(() => {
  let adjustSkillGrade = Math.min( 5, Math.max( 1, props.skillGrade ) )
  return "★".repeat( adjustSkillGrade ) + "☆".repeat( 5 - adjustSkillGrade )
})
</script>

<template>
  <tr>
    <td>{{ name }}</td>
    <td>{{ skillGradeStar }}</td>
  </tr>
</template>
Nia-TN-SDfs-normal2.png
コンポーネントの記述がちょっと楽にになりました

あと、Viteではプロジェクト直下にあるindex.htmlを読み込む仕様なので、index.htmlをプロジェクト直下に移動しました。

3. Vue 3にアップデート&Viteに変更で遭遇したトラブル

3.1. Viteでビルドすると、「URI malformed」のエラーが発生する

これはindex.htmlに設定していた、ファビコンのURIに「<%= BASE_URL %>」が含まれていたのが原因でした。

ファビコンはビルド時にindex.htmlと同じディレクトリに配置されるので、URIから「<%= BASE_URL %>」を取り除き、解決しました。

<!-- Viteでビルドするとエラーになる -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

<!-- 修正後 -->
<link rel="icon" href="/favicon.ico">

3.2. 画面に何も表示されない(ビルドしても、JavaScriptが出力されない)

Vue CLIの場合は、ビルド時に出力されたindex.htmlに、ビルドされたJavaScriptファイルを読み込む <script> タグが自動的に挿入されます。

Viteの場合は、index.htmlに エントリポイントのTypeScriptファイルを読み込む <script> タグを明示的に入れる必要があります。

<script type="module" src="/src/main.ts"></script>
Nia-TN-SDfs-panic.png
これを忘れていて、デバッグし始めた時に、画面が真っ白で焦りました

3.3. <router-link> の tag プロパティは利用不可 → 必ず <a> タグがレンダリングされる

ナビゲーションメニューには、<ul> タグの中に入れた <router-link>tag プロパティを li にセット( <li> タグがレンダリングされる)して構成していました。

<ul>
  <router-link tag="li"> ... </router-link>
  <router-link tag="li"> ... </router-link>
  ...
</ul>

しかし、Vue 3用のvue-router(バージョン4)の <router-link> では、tag プロパティがオミットされてしまい、必ず <a> タグがレンダリングされるようになったので、<ul> タグを <nav> タグに変更し、CSSを修正して、なんとか以前のレイアウトを復元しました。

<nav>
  <router-link> ... </router-link>
  <router-link> ... </router-link>
  ...
</nav>
Nia-TN-SDfs-sweet.png
今回のアップデート作業で一番大変だったのは、ナビゲーションメニューをはじめとしたCSSの修正です。
デバッグし始めた頃は、表示がかなり崩れていました(汗)

4. おわりに

修正がちょっと大変でしたが、無事にポートフォリオのVue.jsのアップデート作業を完了できました。

ちなみにViteはVue.jsの他にReactでも利用できるので、今後新たにReactを使用する機会がある時にも効率よく開発できそうです。

Nia-TN-SDfs-normal2.png
勤め先のエンジニア仲間にも、Viteをちょっと勧めてみようかな

[END]

タイトルとURLをコピーしました