自己紹介
はじめまして、今年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にもご興味のある方は、ぜひ関連する記事についてもご覧いただければと思います。
オプティムでは、新しいことにも挑戦できるエンジニアを随時募集しております!ご興味のある方はこちらをご覧ください。