Nuxt.js + TypeScriptで新規プロジェクト作成

自己紹介

はじめまして、今年3月に中途入社しましたAI/IoTサービス開発部のIoTサービス開発ユニットの下村です。現在、OPTiM IoTでフロントエンド開発をしております。 今回は、そのOPTiM IoTで取り入れたNuxt.js + TypeScriptの新規プロジェクト作成についてご紹介致します。

目次

はじめに

OPTiM IoTプロダクトでは、Nuxt.js及びTypeScriptを初めて触るメンバーがほとんどでしたが、そんな中Nuxt.jsとTypeScriptで開発を進めるに至った経緯についてご説明します。

そもそもNuxt.jsとは、Vue.jsをベースとしたフレームワークです。 Nuxt.jsの特徴の一つとしてあげられる、ページのルーティングがあります。Vue.jsでは必須だったページのルート設定が、pagesフォルダの配下に.vueファイルを作成するだけ自動的にページのルートを生成してくれます。その他、共通レイアウトについて(アプリのヘッダーレイアウトなど)はlayoutフォルダ配下にdefault.vueを用意することでデフォルトの共通レイアウトとして簡単に用意することができます。 このように、Vue.jsでは自身で用意しなければいけなかった設定を簡単にしてくれるなどの点から、 Nuxt.jsの方が導入や運用が簡単になるのではないかと考え採用に至りました。 また、TypeScriptについては複数メンバーが同時に実装を進めることもあり、型安全を守ることでバグの件数を減らす目的で採用しました。

本記事では、これらの組み合わせにて新規プロジェクトを作成する方法についてご紹介致します。

新規プロジェクトの作成

プロジェクトを新規作成したいディレクトリで下記のコマンドを実行します。

$ npm init nuxt-app sample-project

実行を行うとインストール時に幾つかの質問をされるので回答を行います。

Project name: 上記で入力したプロジェクト名を入力
Programming language: TypeScriptを選択する  
Package manager: Npmを選択する
UI framework: Vuetify.jsを選択する
Nuxt.js modules: Axios - Promise based HTTP clientを選択する
Linting tools: ESLintを選択する
Testing framework: Jestを選択する
Rendering mode: Single Page Appを選択する
Deployment target: Static (Static/Jamstack hosting)を選択する
Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)を選択する
Continuous integration: Noneを選択する
Version control system: Gitを選択する

最後まで質問に回答すると、プロジェクトを起動できる状態になります。

下記のコマンドを実行して起動を確認します。

作成したディレクトリへ移動

$ cd sample-project

起動

$ npm run dev

localhost: 3000で正しく表示されることを確認します。 下図の画面が表示されれば成功です!

ディレクトリ構成を変更する

フロント側のソースをsrcというディレクトリにまとめます。 Vue.jsでは、ルーティングを一つずつ実装する必要がありますが、Nuxt.jsではPages下にあるindex.vueが勝手にルートなりますので、routerディレクトリについては不要となります。

|-- src
    |-- assets
    |-- components
    |-- layouts
    |-- locales
    |-- middleware
    |-- pages
    |-- plugins
    |-- store
    |-- types
    |-- utils
|-- nuxt.config.js
|-- pachage.json
|-- tsconfig.json

ディレクトリを作成、移動させたら次にnuxt.config.jsの設定を変更します。

// nuxt.config.js
・・・
srcDir: 'src/',
・・・

この設定を行うことで、src直下のソースを参照できるようになります。 再度起動を確認して、正しくシステムが稼働することを確認してみましょう。

store環境構築

VuexとTypeScriptの相性はあまり良くないと言われておりますが、その中でもNuxt.js公式で推奨されているvuex-module-decorators(github)を用いてstoreを呼び出した時の型安全を守りながら実装を進める方法についてご紹介します。

$ npm install -D vuex-module-decorators

(今回は、いくつかのstoreを用意する予定があったため、modulesフォルダの中に機能ごとの.tsファイルを作成しております。)

// store/modules/sample.ts

import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

@Module({
  name: 'modules/Sample',
  namespaced: true,
  stateFactory: true
})
export default class SampleModule extends VuexModule {
  public sampleText: string = 'Hello World'

  @Mutation
  public setSampleText(value: string) {
    this.sampleText = `${value}さん Hello World!!`
  }

  public get getSampleText(): string {
    return this.sampleText
  }
}
// ~/store/index.ts

import { Store } from 'vuex'
import { initialiseStores } from '../utils/store-accessor'
const initializer = (store: Store<any>) => initialiseStores(store)
export const plugins = [initializer]
export * from '../utils/store-accessor'
// ~/utils/store-accessor.ts

import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import SampleModule from '../store/modules/Sample'

// eslint-disable-next-line import/no-mutable-exports
let SampleStore: SampleModule

function initialiseStores(store: Store<any>): void {
  SampleStore = getModule(SampleModule, store)
}

export { initialiseStores, SampleStore }

コンポーネントからstoreを呼び出す

コンポーネントの実装を行う前に、nuxt-property-decoratorをインストールします。nuxt-property-decoratorはVueを継承したクラスと定義することができるようになります。

$ npm install -S nuxt-property-decorator
// ~/components/Sample/index.vue

<template>
  <h1 style="text-align: center">{{ sampleText }}</h1>
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator';
import { SampleStore } from '../../store'

@Component({
  name: 'SampleComponent'
})
export default class SampleComponent extends Vue {
  private sampleText: string = ''
  public created() {
    SampleStore.setSampleText('shimomura')
    this.sampleText = SampleStore.getSampleText
  }
}
</script>

プロジェクト作成時に用意されていた、pagesのindex.vueを下記の通り書き換えます。

// ~/pages/index.vue

<template>
  <sample-component />
</template>

これで、無事storeへのアクセスと表示を行うことができました。

まとめ

Nuxt.jsではVue.jsに比べルーティングの定義が不要であったり、すでに用意されているライブラリを使用することで、TypeScriptの導入も比較的簡単に行えるのが良いなと感じました!

OPTiM IoTでは、今回ご紹介できませんでしたが、BFF(backend for frontend)側ではOPTiM Cloud IoT OS(CIOS)と連携を行いデバイスの取得処理などを行なっております。CIOSにもご興味のある方は、ぜひ関連する記事についてもご覧いただければと思います。

オプティムでは、新しいことにも挑戦できるエンジニアを随時募集しております!ご興味のある方はこちらをご覧ください。

www.optim.co.jp