Nuxt: npm install からMySql-DBとの接続まで
March 7, 2020 – 3:24 pmWebアプリケーション作成用のフレームワークのNUXTJSに興味を持った。
このフレームワークの枠組みについて一通り理解するために、我がLinuxサーバ上にこれをインストールし、MySQL DBにアクセスし、DB上のデータをWeb上に描画するまでを実際にやってみた。
作業内容について比較的詳細にメモしておいた。
NUXTのインストールと初期設定
node, npm のversion:
$ node -v v10.16.3 $ npm -v 6.14.2
Nuxt の npm install
$ cd sample-app $ npm init -y
$ npm install nuxt --save npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3. > core-js@2.6.11 postinstall /home/node/nuxt_trial/trial-app/node_modules/core-js > node -e "try{require('./postinstall')}catch(e){}" Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library! The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: > https://opencollective.com/core-js > https://www.patreon.com/zloirock Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -) > ejs@2.7.4 postinstall /home/node/nuxt_trial/trial-app/node_modules/ejs > node ./postinstall.js Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/) > nuxt@2.11.0 postinstall /home/node/nuxt_trial/trial-app/node_modules/nuxt > opencollective || exit 0 :-: .==-+: .==. :+- .-=- .==. :==++-+=. :==. -**: :+=. :+- :*+++. .++. :+- -*= .++: .=+. -+: =*- .+*: .=+: -+: .=*- .=*- =+: .==: .+*: -*- -+- .=+:.....:+*-.........:=*=..=*- .-=------=++============++====: Thanks for installing nuxtjs � lease consider donating to our open collective to help us maintain this package. (省 略) + nuxt@2.11.0 added 1064 packages from 490 contributors and audited 10035 packages in 39.18s found 0 vulnerabilities
package.json の編集
package.json:
{ "name": "sample-app", "version": "1.0.0", "config": { "nuxt": { "host": "0.0.0.0", "port": "8080" } }, "scripts": { "dev": "nuxt" }, "dependencies": { "nuxt": "^2.11.0" } }
Nuxt の標準的な Directory を構成:
Directory の確保:
$ mkdir assets components layouts middleware pages plugins static store
Directory 構成と 最小限のファイルの作成・配置:
sample-app --+- package.json +- nuxt.config.json +- assets +- components -- Logo.vue +- layouts -- default.vue +- middleware +- pages -- index.vue -- about.vue +- plugins +- static -- favicon.ico +- store
/components/Logo.vue:
<template> <svg class="NuxtLogo" width="245" height="180" viewBox="0 0 452 342" xmlns="http://www.w3.org/2000/svg"> <g fill="none" fill-rule="evenodd"> <path d="M139 330l-1-2c-2-4-2-8-1-13H29L189 31l67 121 22-16-67-121c-1-2-9-14-22-14-6 0-15 2-22 15L5 303c-1 3-8 16-2 27 4 6 10 12 24 12h136c-14 0-21-6-24-12z" fill="#00C58E" /> <path d="M447 304L317 70c-2-2-9-15-22-15-6 0-15 3-22 15l-17 28v54l39-67 129 230h-49a23 23 0 0 1-2 14l-1 1c-6 11-21 12-23 12h76c3 0 17-1 24-12 3-5 5-14-2-26z" fill="#108775" /> <path d="M376 330v-1l1-2c1-4 2-8 1-12l-4-12-102-178-15-27h-1l-15 27-102 178-4 12a24 24 0 0 0 2 15c4 6 10 12 24 12h190c3 0 18-1 25-12zM256 152l93 163H163l93-163z" fill="#2F495E" fill-rule="nonzero" /> </g> </svg> </template> <style> .NuxtLogo { animation: 1s appear; margin: auto; } @keyframes appear { 0% { opacity: 0; } 100% { opacity: 1; } } </style>
/layouts/default.vue:
<template> <div> <nuxt /> </div> </template> <script> </script> <style> html { font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 16px; word-spacing: 1px; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; box-sizing: border-box; }
ブラウザ上への描画に必要なpages配下のテスト用vueファイルの作成・配置
/pages/index.vue:
<template> <div class="container"> <logo /> <div> <h1>{{ title }}</h1> <Nuxt-Link to="/about">about</nuxt-link> </div> </div> </template> <script> import Logo from '~/components/Logo.vue' export default { components: { Logo }, data() { return { title: 'Sample-app' } } } </script> <style> .container { text-align: center; margin-top: 150px; font-size: 20px; } </style>
/pages/about.vue:
<template> <div class="container"> <logo /> <h1>{{ title }}</h1> <Nuxt-Link to="/">Top</Nuxt-Link> </div> </template> <script> import Logo from '~/components/Logo.vue' export default { components: { Logo }, data() { return { title: 'about' } } } </script> <style> .container { text-align: center; margin-top: 150px; font-size: 20px; } </style>
ブラウザへの描画 実行:
実行コマンド コンソール出力部
$ npm run dev > sample-app@1.0.0 dev /home/user01/sample-app > nuxt ╭─────────────────────────- │ │ │ Nuxt.js v2.11.0 │ │ Running in development mode (universal) │ │ │ │ Listening on: http://192.168.11.111:8080/ │ │ │ ╰────────────────────────── ℹ Preparing project for development ℹ Initial build may take a while ✔ Builder initialized ✔ Nuxt files generated ✔ Client Compiled successfully in 5.08s ✔ Server Compiled successfully in 3.12s ℹ Waiting for file changes ℹ Memory usage: 171 MB (RSS: 230 MB)
apache virtual hosts関連部 (ブラウザに出力)
/etc/httpd/conf.d/vhost.conf:<VirtualHost *:80> ServerName node.yamasnet.com RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </VirtualHost> <VirtualHost *:443> ServerName node.yamasnet.com ServerAdmin webmaster@yamasnet.com DocumentRoot /var/www/node ProxyRequests Off ProxyVia Off RewriteEngine On RewriteCond %{REQUEST_URI} ^/socket.io [NC] RewriteCond %{QUERY_STRING} transport=websocket [NC] RewriteRule /(.*) ws://localhost:8080/$1 [P,L] <Proxy *> Require all granted </Proxy> proxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ SSLEngine on SSLHonorCipherOrder on Header set Strict-Transport-Security "max-age=31536000; includeSubDomains" SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 SSLCertificateFile /etc/letsencrypt/live/yamasnet.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/yamasnet.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/yamasnet.com/chain.pem Protocols h2 http/1.1 </VirtualHost>
ブラウザへの出力:
Top-page(index.vueに対応)
Top-page(index.vueに対応)
npm パッケージの取り込み(パッケージ momentを例に)
package moment の npm install:
$ npm install moment --save
/pages/index.vue:
<template> <div class="container"> <logo /> <div> <h1>{{ title }}</h1> <Nuxt-Link to="/about">about</nuxt-link> <p> now: {{ now }} </p> </div> </div> </template> <script> import Logo from '~/components/Logo.vue' import moment from 'moment' export default { components: { Logo }, data() { return { title: 'Sample-app' } }, computed: { now() { let strfmt ='YYYY-MM-DD HH:mm:ss dddd' return moment().format(strfmt) } }, } </script> <style> .container { text-align: center; margin-top: 150px; font-size: 20px; } </style>
Top-page(index.vueに対応) momentを取り込み時刻を出力
MySQL DBとの接続
npm パッケージ express, axios, mysqlをインストール
$ npm install express axios mysql --save npm WARN sample-app@1.0.0 No description npm WARN sample-app@1.0.0 No repository field. npm WARN sample-app@1.0.0 No license field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.2 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.11 (node_modules/watchpack/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + axios@0.19.2 + mysql@2.18.1 + express@4.17.1
package.json:
{ "name": "sample-app", "version": "1.0.0", "config": { "nuxt": { "host": "0.0.0.0", "port": "8080" } }, "scripts": { "dev": "nuxt" }, "dependencies": { "axios": "^0.19.2", "express": "^4.17.1", "moment": "^2.24.0", "mysql": "^2.18.1", "nuxt": "^2.11.0" } }
外部APIをたてる
外部API用ディレクトリ serverの確保し、そこにapi.jsを作成
$ mkdir server $ vi api.js
api.js:
const express = require('express') const app = express() module.exports = { path: '/server', handler: app } app.get('/hello', (req, res) => { const mysql = require('mysql') const connection = mysql.createConnection({ host : 'localhost', user : 'user', database: 'BookDB', password: 'password' }) connection.connect() let sql ='select * from book_table' connection.query(sql, function(error, row, fields) { if (error) { console.log(error); } let dat = []; for (let i=0; i<row.length; i++) { dat.push({id: row[i].book_id, title: row[i].title, author: row[i].author}) } ret = JSON.stringify(dat) res.send( ret ) }) connection.end() })上記 api.jsではMySQL DBのサンプル用に作成したBookDBをテストデータとして用いた。BookDBの内容については、MySQLを学習(3):INSERT文を用いたData入力フォーム作成参照
外部API(/server/api.js)をNUXTに取り込むためnuxt.config.jsにmoduleとして登録
nuxt.config.js:
module.exports = { serverMiddleware:['~/server/api.js'], }
/pages/index.vueをMySQL DBを受け取りブラウザ上に反映するよう修正
/pages/index.vue:
<template> <div class="container"> <logo /> <div> <h1>{{ title }}</h1> <Nuxt-Link to="/about">about</nuxt-link> <p> now: {{ now }} </p> <ul> <li v-for="post in posts" :key=post.id> {{post.id}} {{post.title}} {{post.author}} </li> </ul> </div> </div> </template> <script> import Logo from '~/components/Logo.vue' import moment from 'moment' import axios from 'axios' export default { components: { Logo }, data() { return { title: 'Sample-app', posts: [] } }, mounted() { axios.get('/server/hello') .then(response => this.posts = response.data) }, computed: { now() { let strfmt ='YYYY-MM-DD HH:mm:ss dddd' return moment().format(strfmt) } }, } </script> <style> .container { text-align: center; margin-top: 150px; font-size: 20px; } </style>
ブラウザへの描画・実行
$ npm run dev (以下 省略)
ブラウザへの出力:
Top-page(index.vueに対応)