こんにちは!
最近ではフロントエンドを Typescript で実装するケースが非常に増えてきました。Typescript を使用することで、複雑になりやすいフロントエンド開発を安全・堅牢に実装することが可能になります。
加えて、Amplify を使用した graphql 実装を行う際、schema.graphql のデータ定義から自動的に API の型情報を生成することができるため、graphql 開発とも相性が良いと言えます。
読者の皆さんも本記事を参考にしていただき、NuxtJS の Typescript にチャレンジしてみてください!
本記事は「NuxtJS の Typescript 環境構築方法」について解説しますので、Typescript の詳しい実装内容には触れていません。
また、本記事は NuxtJS 環境への Typescript 環境構築方法について重点的に解説するため、非 Typescript の NuxtJS 環境への Typescript 設定方法の解説をいたします。
Typescript のビルドに必要なパッケージをインストールします。インストールしたパッケージは、「nuxt.config.js」へ設定(後述)します。
yarn add --dev @nuxt/typescript-build @nuxt/types
NuxtJS には Webpack が内包されています。その Webpack でビルドを行う際に Typescript 用のモジュールを指定します。これにより、Typescript のシンタックスを *.vue
ファイル内で扱うことが可能となります。
/nuxt.config.js
export default {
...
buildModules: ['@nuxt/typescript-build']
...
}
NuxtJS の buildModules に指定した Typescript のビルドモジュールが使用する設定ファイルをプロジェクトのルートディレクトリに作成します。
/tsconfig.json
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "Node",
"lib": [
"ESNext",
"ESNext.AsyncIterable",
"DOM"
],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": true,
"experimentalDecorators": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
"@nuxt/types",
"node"
]
},
"exclude": [
"node_modules",
".nuxt",
"dist",
"coverage"
],
}
Typescript 用の Lint モジュールをインストールし、設定ファイルを作成します。
yarn add -D @nuxtjs/eslint-config-typescript eslint-plugin-prettier eslint-plugin-nuxt prettier eslint-config-prettier
/.eslintrc.yml(好みで json にしてください)
root: true
env:
browser: true
node: true
extends:
- '@nuxtjs'
- '@nuxtjs/eslint-config-typescript'
- 'plugin:prettier/recommended'
- 'plugin:nuxt/recommended'
/.prettierrc
{
"semi": false,
"singleQuote": true
}
/ nuxt.config.js
export default {
...
typescript: {
typeCheck: {
eslint: {
files: './**/*.{ts,vue}',
},
},
}
...
}
エディターが WebStorm( JetBrains 系)の場合は、ファイル保存時に自動実行を設定しておきましょう。
これで基本的な設定は完了です!
次は、私たちが普段採用している Typescript 環境のカスタム内容をご紹介します👍
Vue ファイルで Typescript を扱う場合、5つのシンタックスを選択することができます。
私たちは、State への型をつけやすさ・保守性の高さから、上記のうち Class-Style Vue Components を使用し実装を行っています。(後述)どれが正解ということもないので、好みの方法で実装を行ってください。
Vue に慣れているエンジニアが多数いるのであれば、癖のない Vue.component を使用するのも一つだろうと感じます。詳しくは公式をご覧ください。
以下に Class-Style Vue Components による Vue ファイル実装例をご紹介します。
yarn add -D vue-property-decorator
/pages/products.vue
import { Component, Vue } from 'vue-property-decorator';
type Product = {
id: string
name: string
price: number
}
@Component({
middleware: ['withMiddleware'], // middlewareを使用したい場合に設定
head() {
return {
title: '商品一覧',
}
},
})
export default class SampleComponent extends Vue {
// state
products: Product[] = []
// computed
get getProducts() {
return this.products;
}
mounted(){
this.fetchProducts()
}
// methods内に設定する関数
onClickProduct(product:Product){
alert(product)
}
// methods内に設定する関数
fetchProducts(){
// 商品取得処理情報取得処理
this.products = [
{
id: 1,
name: "イヤホン",
price: 5980,
},
{
id: 2,
name: "ドライヤー",
price: 9250,
}
];
}
}
Vue を都度 import したくない場合、以下のように Typescript にグローバルにVue を宣言することを検討してみてください。
/global.d.ts
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
最後に、Store を Class 化する手順を紹介します。Store も Vue ファイル同様複数実装パターンがありますが、私たちはプロジェクトに応じて以下の2パターンを使い分けています。
従来の Vuex を TS 実装したパターンです。もともと Vue 実装に慣れている方は馴染みやすいかなと感じます。既存の Vue プロジェクトを移行する必要がある場合は、こちらを採用することがしばしばあります。
import { GetterTree, ActionTree, MutationTree } from 'vuex'
export const state = () => ({
things: [] as string[],
name: 'Me',
})
export type RootState = ReturnType<typeof state>
export const getters: GetterTree<RootState, RootState> = {
name: state => state.name,
}
export const mutations: MutationTree<RootState> = {
CHANGE_NAME: (state, newName: string) => (state.name = newName),
}
export const actions: ActionTree<RootState, RootState> = {
async fetchThings({ commit }) {
const things = await this.$axios.$get('/things')
console.log(things)
commit('CHANGE_NAME', 'New name')
},
}
Vue ファイルを Class で実装するなら、全体的に統一感が出るためこちらの Class 型の実装を推奨します。アノテーションを使用し、Class 内のメンバーにオプションを付与します。私たちは保守性の高さからこちらの実装パターンを推奨しています。
yarn add -D vuex-module-decorators
import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
import { $axios } from '~/utils/api'
import { Product } from '~/types'
@Module({
name: 'products',
stateFactory: true,
namespaced: true,
})
class ProductModule extends VuexModule {
products: Product[] = []
@Mutation
setProducts(products: Product[]) {
this.products = products
}
@Action
async getProducts() {
const products = await $axios.$get('/products')
this.setProducts(products)
}
}
NuxtJS・Vue で大規模開発を行うなら Typescript は必須と言えます。
ReactJS のような堅牢な JS 実装と、Vue ならではの美しい HTML を両方活かすことが可能となり、フロントエンドで高い開発効率を実現することができます。もしこれから新規開発のプロジェクトがあるなら、ぜひぜひ導入を検討してみてください!
フロントエンドの Typescript 開発は気軽に問い合わせください。
スモールスタート開発支援、サーバーレス・NoSQLのことなら
ラーゲイトまでご相談ください
低コスト、サーバーレスの
モダナイズ開発をご検討なら
下請け対応可能
Sler企業様からの依頼も歓迎