フロントエンドを Vue.js、バックエンドを Rails で開発している個人サービスの、フロントエンド環境をアップデートしました。
具体的には、Vue.js を 2 系 から 3 系 にアップデートし、新たにTypeScript を導入しました。
Vue.js 3 系と TypeScript の組み合わせについては、新しく規開発し始める場合の方法に関する情報は豊富なものの、既に動いている既存のサービスに導入する方法はほとんどありませんでした。
また
また、現サービスはバンドルツールとしてRails標準の Webpacker を利用していますが、Webpacker に言及している情報もかなり少なかったです。
Vue のアップデートと TypeScript の導入に際して、いくつかハマりどころがありましたので、私が実施した手順について簡単に紹介します。
Vue2系 から Vue3 系へのアップデート手順
ライブラリのインストール
vue, vue-loader compiler-sfc について、最新バージョンをインストールします。
なお、vue3 に対応しているライブラリは、next のタグが付いているケースが多いです。
yarn add vue@next vue-loader@next @vue/compiler-sfc
コマンド実行後の package.json は下記のように更新されているはずです。
// package.json
{
// ...
"dependencies": {
+ "@vue/compiler-sfc": "^3.0.11",,
- "vue": "^2.6.12",
- "vue-loader": "^15.9.6",
+ "vue": "^3.0.11",
+ "vue-loader": "^16.2.0",
// ...
}
// ...
}
Tree Shaking の有効化(任意)
Tree Shaking を適切に利用するために、Bundler Build Feature Flag を定義します。
Bundler Build Feature Flag とは__VUE_OPTIONS_API__
や__VUE_PROD_DEVTOOLS__
のことで、バンドルツールがバンドルする際のフラグです。
ちなみに、Tree Shaking とは Webpack でファイルをバンドルする際に、利用されていない不要なコードを除去して、バンドルサイズを小さくする仕組みのことです。
Webpack の設定に下記を追加します。
なお、従来の Options API を利用する場合は、__VUE_OPTIONS_API__: false,
は定義してはいけません。(Default で true になっています。)
//...
const { DefinePlugin } = require('webpack')
environment.plugins.prepend(
'Define',
new DefinePlugin({
__VUE_OPTIONS_API__: false,
// or __VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
})
)
//...
Composition API に書き換える(任意)
Options API に変わり Composition API を利用する場合は SFC を書き変えましょう。
Composition API の利用方法については、ドキュメント に詳しく記載がありますので、ご参考ください。
参考
- Vue.js 3 · Issue #2751 · rails/webpacker · GitHub
- Vue3 on Rails - DEV Community
- Migrating Vue 2 to Vue 3
- Vue 2で書かれた個人プロジェクトをVue 3に書き換えてみた - クラシル開発ブログ
Typescript の導入手順
Webpacker を使い TypeScript 追加する
TypeScript の導入は Webpacker を利用する方法が一番簡単です。
Webpacker 前提ではない場合はyarn add ts-loader
で ts-loader を追加して一からセットアップする方法が主流のようですが、せっかく Webpacker を使っているので Webpacker の恩恵に預かることにします。
rails webpacker:install:typescript
ts-loader の設定追加
ts-loader の設定を追加します loader の設定ファイルは Webpack の設定ファイルに定義しても良いですが、外部ファイル化するほうが見通しが良くなるため、外部ファイル化しています。
module.exports = {
test: /\.tsx$/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/],
},
exclude: /node_modules/,
}
const ts = require("./loaders/ts")
//...
environment.loaders.prepend("ts", ts)
tsconfig の修正をする
rails webpacker:install:typescript
コマンド実行時に追加された tsconfig.json に コンパイル対象のパスを定義します。
なお、 tsconfig.json とは TypeScript の設定ファイルで、コンパイルのオプションや TypeScript ファイルの対象や対象外のパスの設定することができます。
プロジェクトごとに異なりますが.ts
と SFC のために .vue
のパスを追加します。
下記は私が定義したパスの一例です。
{
//...
"include": [
"app/javascript/**/*.ts",
"app/javascript/**/*.vue",
],
//...
}
型定義ファイルを追加する
上記のapp/javascript/**/*.ts
のパス内に SFC からエクスポートしたコンポーネントの型定義ファイルを追加します。
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
この型定義をしないと、VSCode 上(私の使用エディタ)でモジュール 'app/javascript/components/ContactForm/index.vue' またはそれに対応する型宣言が見つかりません。
のような Warning が出ます。
上記で定義した tsconfig.json の include に定義したパスを間違えている場合も同様の Warning が出ますので、 Warning が出たらパスを確認してみると良いです。
TypeScript の動作確認
これまでの手順で、 TypeScript のセットアップは完了しています。
動作確認のために、 app/javascript/packs/example.js
などの既存のエントリーファイルを拡張子を .ts に書き換えてみましょう。
また。app/javascript/components/example.vue
などの既存の SFC ファイルの lang を ts に指定してみましょう。
//...
<script lang='ts'>
//...
</script>
//...
コンポーネントの振る舞いがこれまで通りであれば、TypeScript の導入が完了です。お疲れさまでした。