はじめに
PWAのアプリを、Nuxt.jsとTypeScriptで構築し、
コンポーネントをCompositionAPIを使った構成を、
AWS Amplifyにデプロイしたいと思います。
実行環境のバージョン
node.js : 12.13.1
create-nuxt-app : 2.12.0
実装
プロジェクトの作成
Nuxt.jsのプロジェクトを作成する。
$ npm install -g create-nuxt-app
$ create-nuxt-app nuxt-pwa-for-composition # nuxt-pwa-for-compositionはプロジェクト名
対話形式で作成するNuxt.jsの構成を入力します。
この記事では、構成は以下のようにしました。
? Project name _ # デフォルトのままEnter
? Project description _ # デフォルトのままEnter
? Author name _ # デフォルトのままEnter
? Choose the package manager Npm
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support, DotEnv
? Choose linting tools ESLint, Prettier, StyleLint
? Choose test framework Jest
? Choose rendering mode Single Page App
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to i
nvert selection)
最低でも、Choose Nuxt.js modules
にProgressive Web App (PWA) Support
を入れてください。
$ cd nuxt-pwa-for-composition
$ npm run dev
ERROR in No rules found within configuration. Have you provided a "rules" property?
このようなエラーが出ました。
stylelint.config.js
にrules
が記述されていないとのことなので追加します。
module.exports = {
rules: {
'at-rule-no-unknown': [
true,
{
ignoreAtRules: ['extends', 'ignores']
}
],
indentation: 2,
'number-leading-zero': null,
'unit-whitelist': ['px', 'deg', 'em', 'rem', 's']
}
}
再び起動
$ npm run dev
今回は問題なく、実行できたかと思います。
ポートが使われていないのであればhttp://localhost:3000
でページが表示されるはずです。
TypeScriptの反映
このガイドの内容を中心に構築します。
https://typescript.nuxtjs.org/guide/
必要なライブラリをインストールします。
$ npm install --save-dev @nuxt/typescript-build @nuxtjs/eslint-config-typescript
$ npm install @nuxt/typescript-runtime
次のファイルを更新もしくは追加します。
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module',
// Doc: https://github.com/nuxt-community/stylelint-module
'@nuxtjs/stylelint-module',
- '@nuxtjs/vuetify'
+ '@nuxtjs/vuetify',
+ '@nuxt/typescript-build'
],
・・・
build: {
/*
** You can extend webpack config here
*/
- extend(config, ctx) {}
+ extend() {}
}
}
"scripts": {
- "dev": "nuxt",
+ "dev": "nuxt-ts",
- "build": "nuxt build",
+ "build": "nuxt-ts build",
- "start": "nuxt start",
+ "start": "nuxt-ts start",
- "generate": "nuxt generate",
+ "generate": "nuxt-ts generate",
- "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
+ "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .",
"test": "jest"
},
parserOptions: {
- parser: 'babel-eslint'
},
・・・
extends: [
'@nuxtjs',
+ '@nuxtjs/eslint-config-typescript',
'prettier',
'prettier/vue',
'plugin:prettier/recommended',
'plugin:nuxt/recommended'
],
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"lib": [
"esnext",
"esnext.asynciterable",
"dom"
],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
"@nuxt/types",
"vuetify"
]
},
"exclude": [
"node_modules"
]
}
Composition APIの適用
コンポーネントには、Vue 3で採用される予定のComposition APIを採用しようと思います。
Composition APIの説明はこの記事では行いません。
ドキュメントはこちら
投稿時点では、Class APIの情報の方が多い気がするので、
Class APIを採用しても良いとは思います。
$ npm install --save @vue/composition-api
import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'
Vue.use(VueCompositionApi)
generateされた.vue
ファイルがいくつかあるので、
そのファイルをComposition APIの記述に変えていきます。
※バージョンアップによりtemplateが変更になるのであれば、
こちらの記述では動作しなくなる可能性があります。
<script lang="ts">
import { createComponent } from '@vue/composition-api'
export default createComponent({})
</script>
<script lang="ts">
import { createComponent } from '@vue/composition-api'
export default createComponent({})
</script>
<script lang="ts">
import { createComponent, ref } from '@vue/composition-api'
interface Item {
icon: string
title: string
to: string
}
const useMenus = () => {
const clipped = ref<boolean>(false)
const drawer = ref<boolean>(false)
const fixed = ref<boolean>(false)
const items = ref<Item[]>([
{
icon: 'mdi-apps',
title: 'Welcome',
to: '/'
},
{
icon: 'mdi-chart-bubble',
title: 'Inspire',
to: '/inspire'
}
])
const miniVariant = ref<boolean>(false)
const right = ref<boolean>(false)
const rightDrawer = ref<boolean>(false)
return {
clipped,
drawer,
fixed,
items,
miniVariant,
right,
rightDrawer
}
}
export default createComponent({
setup() {
const menus = useMenus()
const title = ref<string>('Vuetify.js')
return {
...menus,
title
}
}
})
</script>
<script lang="ts">
import { createComponent, ref } from '@vue/composition-api'
export default createComponent({
layout: 'empty',
props: {
error: {
type: Object,
default: null
}
},
head() {
const title =
(this as any).error.statusCode === 404
? (this as any).pageNotFound
: (this as any).otherError
return {
title
}
},
setup() {
const pageNotFound = ref<string>('404 Not Found')
const otherError = ref<string>('An error occurred')
return {
pageNotFound,
otherError
}
}
})
</script>
<script lang="ts">
import { createComponent } from '@vue/composition-api'
import Logo from '~/components/Logo.vue'
import VuetifyLogo from '~/components/VuetifyLogo.vue'
export default createComponent({
components: {
Logo,
VuetifyLogo
}
})
</script>
jsファイルをtsファイルにする
+ import { Configuration } from '@nuxt/types'
import colors from 'vuetify/es5/util/colors'
- export default {
+ const nuxtConfig: Configuration = {
mode: 'spa',
・・・
build: {
/*
** You can extend webpack config here
*/
extend() {}
}
}
+ export default nuxtConfig
PWAの修正
アプリアイコンとファビコンを変更する。
- static/favicon.ico
- static/icon.png
余談ですが、とあるカンファレンスのWebページがPWA対応になっていましたが、
アプリアイコンは変えていないようで、Nuxtのアイコンが表示されていました。
GitHubにコミット
以上の内容をGitHubにコミットします。
リポジトリはprivateリポジトリでも問題ありません。
AWS Amplifyの準備
「Deploy With the Amplify Console」の「GET STARTED」を選択します。
GitHub、BitBucket、GitLab、AWS CodeCommitのGitリポジトリを使うことができるようです。
今回はGitHubにpushしましたので、GitHubを選択します。
ビルド設定の構成で、アプリ名を変更してください。
また、frontend.artifacts.baseDirectoryの項目が/
になっているようなら、/dist/
に変更してください。
特に問題内容でしたら、「保存してデプロイ」ボタンを押します。
「検証」までチェックが入ったら完了です。
URLのリンクをクリックし、ちゃんとデプロイできているかを確認します。
Vuetify + Nuxt.jsのtemplateが表示されれば成功です。
Android Chrome等でデプロイされたURLを開きます。
ホームに追加をタップする。
アプリとして表示できれば成功です。
まとめ
今回は、PWAアプリをNuxt.js + TypeScriptで構築する方法と
作成したアプリをAmplify Consoleでデプロイする方法を紹介しました。
SPAをホスティングサービスは多々ありますが、
Amplify ConsoleをCI/CDの管理を気にせずにデプロイすることができるようになるのが大きな利点だと思います。
ただ、今回のサンプルのようにただのホスティングサービスとしてしか使わないと、Amplifyをいかせてはいないとは思います。
また、AWSの資源(カスタムドメイン設定など)を活用しやすいのも利点としてあげれるかと思います。
デプロイ先の一つの候補としてAmplifyを考えてみてはいかがでしょうか。
今回の完成形のリポジトリはこちら