結論をいうと
yarn create nuxt-app ***
amplify init
amplify add api
amplify add auth
amplify push
終わりです、amplifyに全てを委ねてください
amplifyの準備
yarn global add @aws-amplify/cli
amplify configure
これを実行するとブラウザ立ち上がり、AWSのログイン画面になります。 ブラウザでログインを行い、ターミナルへ戻ります。下記の状態になっているので表示通りenterキーを押します。
Follow these steps to set up access to your AWS account:
Sign in to your AWS administrator account:
<https://console.aws.******.com/>
Press Enter to continue
するとIAMのユーザーを作成するための設定を対話形式で行っていく形になります。 途中またブラウザに戻りAWSのIAMのコンソールでユーザー作成する画面に遷移します。そこで、画面にそってユーザーを作成します。最終的に発行したユーザーのaccessKeyIdとsecretAccessKeyを対話型コマンドラインに入力します。
Enter the access key of the newly created user:
? accessKeyId: **************
? secretAccessKey: **************
...
Successfully set up the new user.
これで、Amplifyを使う際のアカウント設定が完了します。
nuxt HelloWorld!!
yarn create nuxt-app chat-aws-nuxt
? Project name chat-aws-nuxt
? Project description My peachy Nuxt.js project
? Use a custom server framework none
? Choose features to install Progressive Web App (PWA) Support, Linter / Formatter, Prettier, Axios
? Use a custom UI framework none
? Use a custom test framework jest
? Choose rendering mode Universal
? Author name castleobj
? Choose a package manager yarn
nuxt新しいのがいいので入れ直します
cd chat-aws-nuxt
yarn remove nuxt
yarn add nuxt
yarn dev
ちょっとすみません、fix設定します
package.json
"scripts": {
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore .",
...
},
あ、scssで書きたいです
yarn add node-sass sass-loader -D
個人的な設定を
.eslintrc
rules: {
"no-console": "off"
}
.prettierrc
{
"semi": false,
"singleQuote": true,
"trailingComma": "all", // 追加
}
amplify init
amplify init
? Enter a name for the project chat-aws-nuxt
? Enter a name for the environment master
? Choose your default editor: Vim (via Terminal, Mac OS only)
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using vue
? Source Directory Path: src
? Distribution Directory Path: dist
? Build Command: yarn build
? Start Command: yarn start
Using default provider awscloudformation
For more information on AWS Profiles, see:
https://docs.aws.******.com/cli/latest/userguide/cli-multiple-profiles.html
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
profileは~/.aws/credentialsに記載されている
amplify add api
amplify add api
? Please select from one of the below mentioned services GraphQL
? Provide API name: chatAwsNuxt
? Choose an authorization type for the API API key
? Do you have an annotated GraphQL schema? No
? Do you want a guided schema creation? No
? Provide a custom type name Post
Creating a base schema for you...
GraphQL schema compiled successfully.
Edit your schema at /Users/castleobj/repository/chat-aws-nuxt/amplify/backend/api/chat-aws-nuxt/schema.graphql or place .graphql files in a directory at /Users/castleobj/repository/chat-aws-nuxt/amplify/backend/api/chat-aws-nuxt/schema
Successfully added resource chat-aws-nuxt locally
Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
amplify push
amplify push
Current Environment: master
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | ----------------- |
| Api | chat-aws-nuxt | Create | awscloudformation |
? Are you sure you want to continue? Yes
GraphQL schema compiled successfully.
Edit your schema at /Users/castleobj/repository/chat-aws-nuxt/amplify/backend/api/chat-aws-nuxt/schema.graphql or place .graphql files in a directory at /Users/castleobj/repository/chat-aws-nuxt/amplify/backend/api/chat-aws-nuxt/schema
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
...
GraphQL endpoint: https://※※※.appsync-api.us-east-1.******aws.com/graphql
GraphQL API KEY: ※※※
この情報は src/aws-exports.jsに自動的に挿入されます
src/aws-exports.js
const awsmobile = {
"aws_project_region": "us-east-1",
"aws_appsync_graphqlEndpoint": "https://※※※.appsync-api.us-east-1.******aws.com/graphql",
"aws_appsync_region": "us-east-1",
"aws_appsync_authenticationType": "API_KEY",
"aws_appsync_apiKey": "※※※"
};
export default awsmobile;
これを下に修正(lint)
const awsmobile = {
aws_project_region: 'us-east-1',
aws_appsync_graphqlEndpoint:
'https://※※※.appsync-api.us-east-1.******aws.com/graphql',
aws_appsync_region: 'us-east-1',
aws_appsync_authenticationType: 'API_KEY',
aws_appsync_apiKey: '※※※'
}
export default awsmobile
更新の度に修正は面倒なので.eslintignoreを作成して除外
/.eslintignore
aws-exports.js
yarn add aws-amplify aws-amplify-vue
nuxt.config.js
plugins: [{ src: '~/plugins/amplify.js', ssr: false }],
plugins/amplify.js
import Vue from 'vue'
import Amplify, * as AmplifyModules from 'aws-amplify'
import { AmplifyPlugin, components } from 'aws-amplify-vue'
import awsconfig from '@/src/aws-exports'
Amplify.configure(awsconfig)
Vue.use(AmplifyPlugin, AmplifyModules)
Vue.component(components)
pages/index.vue
<template>
<div class="container">
<div>
<h1 class="title">
chat-aws-nuxt
</h1>
<h2 class="subtitle">
My magnificent Nuxt.js project
</h2>
<div className="App">
<div>
タイトル
<input v-model="state.title" name="title" @change="onChange" />
</div>
<div>
内容
<input v-model="state.content" name="content" @change="onChange" />
</div>
<button @click="createPost">追加</button>
<div v-for="(list, index) in mapPosts" :key="index">
<div>title: {{ list.title }}</div>
<div>content: {{ list.content }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { API, graphqlOperation } from 'aws-amplify'
import { listPosts } from '@/src/graphql/queries'
import { createPost } from '@/src/graphql/mutations'
import { onCreatePost } from '@/src/graphql/subscriptions'
export default {
data() {
return {
state: {
posts: [],
title: '',
content: ''
}
}
},
computed: {
mapPosts() {
return this.state.posts.map((post, idx) => {
return post
})
}
},
async mounted(e) {
try {
const posts = await API.graphql(graphqlOperation(listPosts))
console.log('posts: ', posts)
this.state.posts = posts.data.listPosts.items
} catch (e) {
console.log(e)
}
API.graphql(graphqlOperation(onCreatePost)).subscribe({
next: eventData => {
console.log('eventData: ', eventData)
const post = eventData.value.data.onCreatePost
const posts = [
...this.state.posts.filter(content => {
return content.title !== post.title
}),
post
]
this.state.posts = posts
}
})
},
methods: {
async createPost() {
// バリデーションチェック
if (this.state.title === '' || this.state.content === '') return
// 新規登録 mutation
const createPostInput = {
title: this.state.title,
content: this.state.content
}
// 登録処理
try {
const posts = [...this.state.posts, createPostInput]
this.state.posts = posts
this.state.title = ''
this.state.content = ''
await API.graphql(
graphqlOperation(createPost, { input: createPostInput })
)
console.log('createPostInput: ', createPostInput)
} catch (e) {
console.log(e)
}
},
onChange(e) {
console.log(e)
this['e.target.name'] = e.target.value
}
}
}
</script>
<style lang="scss" scoped>
...
</style>
yarn dev
、、、
styleさわります、、!!、scssで書きたいっていいましたがcss自体書きたくないのでvuetify使います
yarn add @nuxtjs/vuetify
nuxt.config.js
...
modules: [
'@nuxtjs/axios',
'@nuxtjs/pwa',
'@nuxtjs/eslint-module',
'@nuxtjs/vuetify'
],
...
default.vue
<template>
<v-app>
<v-navigation-drawer
v-model="drawer"
:mini-variant="miniVariant"
:clipped="clipped"
fixed
app
>
<v-list>
<v-list-tile
v-for="(item, i) in items"
:key="i"
:to="item.to"
router
exact
>
<v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title v-text="item.title" />
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="primary" :clipped-left="clipped" fixed app dark>
<v-toolbar-side-icon @click="drawer = !drawer" />
<v-btn icon @click.stop="miniVariant = !miniVariant">
<v-icon>{{ `chevron_${miniVariant ? 'right' : 'left'}` }}</v-icon>
</v-btn>
<v-btn icon @click.stop="clipped = !clipped">
<v-icon>web</v-icon>
</v-btn>
<v-btn icon @click.stop="fixed = !fixed">
<v-icon>remove</v-icon>
</v-btn>
<v-toolbar-title v-text="title" />
<v-spacer />
<v-btn icon @click.stop="rightDrawer = !rightDrawer">
<v-icon>menu</v-icon>
</v-btn>
</v-toolbar>
<v-content>
<v-container>
<nuxt />
</v-container>
</v-content>
<v-navigation-drawer v-model="rightDrawer" :right="right" temporary fixed>
<v-list>
<v-list-tile @click.native="right = !right">
<v-list-tile-action>
<v-icon light>compare_arrows</v-icon>
</v-list-tile-action>
<v-list-tile-title>Switch drawer (click me)</v-list-tile-title>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-footer :fixed="fixed" app>
<span>© 2019</span>
</v-footer>
</v-app>
</template>
<script>
export default {
data() {
return {
clipped: false,
drawer: false,
fixed: false,
items: [
{
icon: 'apps',
title: 'Chat',
to: '/'
}
],
miniVariant: false,
right: true,
rightDrawer: false,
title: 'Chat'
}
}
}
</script>
index.vue
<template>
<v-layout row wrap>
<v-flex xs12 class="mb-5">
<v-card>
<v-card-title class="headline">Welcome to Chat</v-card-title>
<div v-for="(list, index) in mapPosts" :key="index">
<v-card-title class="font-weight-bold pb-0">
{{ list.title }}
</v-card-title>
<v-card-text class="font-weight-thin pt-0">{{
list.content
}}</v-card-text>
</div>
</v-card>
</v-flex>
<v-flex xs12>
<v-text-field
v-model="state.title"
label="title"
@change.native="onChange"
></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field
v-model="state.content"
label="content"
@change.native="onChange"
></v-text-field>
</v-flex>
<v-flex xs12>
<v-btn color="primary" @click="createPost">Add</v-btn>
</v-flex>
</v-layout>
</template>
<script>
import { API, graphqlOperation } from 'aws-amplify'
import { listPosts } from '@/src/graphql/queries'
import { createPost } from '@/src/graphql/mutations'
import { onCreatePost } from '@/src/graphql/subscriptions'
export default {
data() {
return {
state: {
posts: [],
title: '',
content: ''
}
}
},
computed: {
mapPosts() {
return this.state.posts.map((post, idx) => {
return post
})
}
},
async mounted(e) {
try {
const posts = await API.graphql(graphqlOperation(listPosts))
console.log('posts: ', posts)
this.state.posts = posts.data.listPosts.items
} catch (e) {
console.log(e)
}
API.graphql(graphqlOperation(onCreatePost)).subscribe({
next: eventData => {
console.log('eventData: ', eventData)
const post = eventData.value.data.onCreatePost
const posts = [
...this.state.posts.filter(content => {
return content.title !== post.title
}),
post
]
this.state.posts = posts
}
})
},
methods: {
// createPost = async () => {
async createPost() {
// バリデーションチェック
if (this.state.title === '' || this.state.content === '') return
// 新規登録 mutation
const createPostInput = {
title: this.state.title,
content: this.state.content
}
// 登録処理
try {
const posts = [...this.state.posts, createPostInput]
this.state.posts = posts
this.state.title = ''
this.state.content = ''
await API.graphql(
graphqlOperation(createPost, { input: createPostInput })
)
console.log('createPostInput: ', createPostInput)
} catch (e) {
console.log(e)
}
},
onChange(e) {
console.log(e)
this['e.target.name'] = e.target.value
}
}
}
</script>
<style lang="scss" scoped></style>
lint系のerrorは
yarn lintfix
で修正しました
universalだとssrの関係で[window is not defined]なのでspaにしました。
Deploy
Amplify Console の手順を説明します。
まずは「AWS Amplify」を選択します。
「GET STARTED」を選択します。
今回は「GitHub」を例にします。
・リポジトリの選択
・ブランチの選択
・ブランチの選択
・ロールの作成
baseDirectoryを「/dist」に修正します。
「保存してデプロイ」
デプロイが終わるまで待ちます。
「検証」までチェックがつけば終わりです。
エラーが出た際はエラーログを確認しましょう。
cognitoの追加
amplify add auth
amplify push
src/aws-exports.jsが書き換わる
コード編集(ログインフォーム、認証処理諸々)
git add -A
git commit -m 'cognito'
git push
awsのコンソールでこちょこちょやらずに、ターミナルからamplifyに全て任せたほうがうまくいった。 amplifyすごい。
カラム追加、テーブル追加
amplify/backend/api/boardappAwsNuxt/schema.graphql
編集
amplify api gql-compile
amplify push
/signinへのリダイレクト追加、nuxtのmiddlewareに書きます。
middleware/auth.js追加
signin.vue追加
pages/index.vue修正
default.vue修正
Photo by JESHOOTS.COM on Unsplash