見出し画像

Vue-CliからViteへ移行する

某Issueの原因を調べている過程でvue-cliの仕様をもう一度見てみようと公式のサイトを久しぶりに訪れてみると、あれ、Viteというビルドツールがでているじゃないか!?と今更ながら気づいた私、、遅ればせながらViteへの移行をやってみました。

今回は既存のプロジェクトをViteへ移行するので、下のサイトがすごく参考になりました。

https://zenn.dev/kazuwombat/articles/9357f6b1ccca8c

こちらの記事の「いざプロジェクトに導入」の章にそのまま従って変更していきました。

そして、恐る恐るyarn serveとyarn buildで動作確認。。。
いくつか見慣れないエラーがでて怯んでしまいましたが、結果的にはどれも大きなも修正を要するものではありませんでした。ただ、すこし苦闘した箇所もあったので参考になればと思いまとめてみます。

Componentのimport

vue-cliではコンポーネントのインポート時に、ファイル拡張子が抜けていても許してくれましたが、viteでbuildするとそこを厳密に見られるようです。
いくつか下のようにimport文にファイル拡張子が抜けている箇所があり、

import SuccessCopyPopup from '@/components/home/SomeComponent';

このようなエラーがでました。

Could not load … ENOENT: no such file or directory, open …

したのように末尾に.vueのファイル拡張子をつけたらエラーは消えました。

import SuccessCopyPopup from '@/components/home/SomeComponent.vue';

SVGファイルの読み込み

次にSVGファイルの読み込みをしているところでエラーがでて、このエラーの理解に時間がかかったので、詳しく解説したいと思います。

私が試したプロジェクトでは、SVGファイルを
1. templateのなかの<img>タグでsrcとして参照している

<img src="@/assets/images/arrow.svg" />

ものと、
2. Vue Componentとして読み込んで使っている

import SomSVGComponent from '@/assets/images/home/someicon.svg?inline';

ものがありました。
この2つのケース両方ともviteでエラーが出ないようにするために、右往左往した結果、以下に説明するやり方が一番良かったです。

vite-svg-loaderをインストール

yarn add -D vite-svg-loader

 で、vite-svg-loaderをインストールします。

imgタグへのsvgファイル読み込み


つぎに、vite.config.jsをひらき、vite-svg-loaderをimportします。(下の3行目)

import vue from '@vitejs/plugin-vue';
import path from 'path';
import svgLoader from 'vite-svg-loader';

export default {
  plugins: [
    vue(),
    svgLoader({
      defaultImport: 'url',
    }),
  ],
  server: {
    port: 8080,
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
};

その後、pluginsセクションの中に、svgLoader()の設定を追加します。この中で、defaultImportというところに、`url`という文字列を設定しました。(上のコードスニペットの8~10行目)

このdefaultImportの設定をしないでviteでビルドすると、下のようなsvgファイルへの参照はエラーとなります。
<img src="@/assets/images/arrow.svg" />

対策として、↓のように?urlをつけると読み込んでくれるようになります。
<img src="@/assets/images/arrow.svg?url" />

?urlをつけることで、ビルドシステムがこのsvgファイルのパスはURLなのだと理解してくれるようです。
ただ、全部のsvgを参照しているimgタグを変更するのはきついですよね?

defaultImportを'url'とすると、この?urlをつけなくても、すべてのsvgのパスをurlだと解釈してくれます。ですので、下のようなタグの定義を変更する必要がなくなります。
<img src="@/assets/images/arrow.svg" />

Vueコンポーネントへのsvgの読み込み

つぎに、VueコンポーネントとしてSVGを読み込んでいる箇所のエラーへの対処を行いました。
いままでは、したのように?inlineというpostfixをつけていた箇所でエラーがでていました。

import SomSVGComponent from '@/assets/images/home/someicon.svg?inline';

この箇所には?componentをつけて下のように変更します。

import SomSVGComponent from '@/assets/images/home/someicon.svg?component';

ここまでの修正で、imgタグのsvgの読み込みも、コード中のsvgの読み込みも両方動くようになりました。


【番外編】VueコンポーネントへのSVGの読み込みをデフォルトにしたい場合

私と違ってimgタグのなかでsvgを使っていなくて、主にVueコンポーネントとして読み込んでsvgファイルを使っている人は以下のようにdefaultImport'component'にする方法が良いと思います。

svgLoader({
  defaultImport: 'component',
}),

こうすると下のようにVueコンポーネントへの読み込みの箇所に、svgファイル名の後に?componentをつける必要がなくなります。

import SomSVGComponent from '@/assets/images/home/someicon.svg';

逆にこの状態で<img>タグでsvgファイルを参照する箇所があれば、そちらのほうに<img src="@/assets/images/arrow.svg?url" />のように?urlを付ける必要があることを覚えておいてください。


まとめますと

defaultImportという設定で設定した文字列が?<文字列>として全てのSVGパスの後ろに付加されるようになる。

<img>タグ、Vueコンポーネント、どちらへの読み込みが多いかに応じて、'url'か'component'を決めて指定すると、変更箇所が少なくてすむ。
(他にも'raw'という文字列をしていしてsvgのパスを文字列として読み込む方法もあるようです)

defaultImportを決めたら、defaultと違うケースのほうのSVGパスには?<文字列>をつけないと正しく読み込めないことに注意する。

<vite-svg-loaderの公式ページ↓>

ここまでやってひとまずアプリは正常に動いていそうです。
vue-cliを使っていたときの残留物がまだ残っていそうなので、このあと時間をかけて取り除いて行き、またそこで発見があったら共有したいと思います!

このブログに関する質問やiOS・Android・Webアプリの開発の相談はこちらから↓↓↓

@mizutory
mizutori@goldrushcomputing.com







この記事が気に入ったらサポートをしてみませんか?