- 投稿日:2020-03-22T20:05:24+09:00
Progate無料版をやってみる【Node.js】
前回に引き続きProgate無料レッスンをやっていこうと思います。
今回はNode.jsです。
Progateの無料版のレッスンはこれで終わります。
以前のレッスンで既にインストール済みです。Node.js
Expressの導入
・ExpressとはNode.jsでWebアプリを開発するためのフレームワーク。
RubyでいうところのRailsになんでしょうね。C#でいうところのASP.NETみたいな。
・おなじみのパッケージ。便利な機能、メソッドが揃った塊、ライブラリの事。
・npm
コマンドでExpressをインストールする。
npm
とはNode Package Manager
その名の通り、Node.jsのパッケージを管理するツール。これを使ってパッケージを取得する。環境
最近こればっかりですが、VSCode使っていきます。適当なデイレトリを作成し
VSVodeで開きます。
ターミナルを開きます。
まずinitします。npm init
package name: (node)
と聞かれた作成するpackage.jsonの名前をいれます。任意な値。nodeにしました。次に、以下を実行してExpressをインストールします。
npm install expressProgateのレッスンにもどります。
Progateのディレクトリ構成を再現します。
C:\job\Node │ app.js │ package-lock.json │ package.json │ ├─node_modules └─public └─imagesapp.js等の中身もコピペします。
app.js
const express = require('express'); const app = express();サーバーの起動
・
app.listen(3000);
と記述することで、ポート3000のhttp通信を受けつけることになるらしい。app.js
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.render('hello.ejs'); }); // サーバーを起動するコードを貼り付けてください app.listen(3000);getのところは、TOP
/
にGET
リクエストがあった場合にhello.ejs
をレンダリングする意味だと思います。
ejs
ってなんすかwProgateを真似すると、Viewsディレクトリが新たにできていて、その中に
hello.ejs
があります。
hello.ejs<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello World</title> <script src="/send_url.js"></script> </head> <body> <h1>Hello World</h1> </body> </html>
/send_url.js
ってなんだ?w
ターミナルでnode app.jsと打って実行します。
http://localhost:3000
にアクセスすると以下のエラーとなった
package.jsonの内容がちがったから、そのせいかな?
一緒にしてみる。package.json
{ "name": "nodejs_lesson", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "eslint": "eslint ./", "start": "nodemon -r './.module' ./app.js" }, "author": "Progate", "license": "ISC", "dependencies": { "ejs": "^2.6.1", "express": "^4.16.4" }, "devDependencies": { "nodemon": "^1.18.10" } }でも同じエラー。
あ、書き換えたpackage.jsonを適用するのかな?と思いnpm updateこれで、package.jsonに記載した
"ejs": "^2.6.1"
が適用されずはず・・・。実行後に
http://localhost:3000
にアクセス。
表示できました!ページの表示の仕組み
・見た目部分には
ejs
という形式のファイルを使い、views
ディレクトリの下に配置するらしい。HTMLと同じと思えとのこと。演習
・新たにtop.ejs
が追加になる。app.js
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.render('hello.ejs'); }); // トップ画面を表示するルーティングを作成してください app.get('/top', (req, res) => { res.render('top.ejs'); }); app.listen(3000);top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <a class="index-button">一覧を見る</a> </div> <div class="top-image"> </div> </div> </body> </html>
npm app.js
してからhttp://localhost:3000/top
にアクセス
CSSの適用と画像の表示
・「Expressでは、CSSや画像などのファイルがどこに置かれているかを指定する必要があります」らしい。
publicにある。
・app.jsでapp.use(express.static('public'));
を行う必要がある。
・Progateの説明の通り、style.css
を追加する。top.ejsで読み込む。app.js
const express = require('express'); const app = express(); // CSSや画像ファイルを置くフォルダを指定するコードを貼り付けてください app.use(express.static('public')); app.get('/', (req, res) => { res.render('hello.ejs'); }); app.get('/top', (req, res) => { res.render('top.ejs'); }); app.listen(3000);public/css/style.css
/* reset ================================ */ * { box-sizing: border-box; } html { font-size: 100%; font-family: 'Hiragino Sans', sans-serif; line-height: 1.7; letter-spacing: 1px; } body { margin: 0; background-color: #f6faff; color: #6c7686; } ul, li { list-style-type: none; padding: 0; margin: 0; } a { display: block; text-decoration: none; color: #2d3133; font-size: 14px; } a:hover { transition: all 0.3s ease; } h1, h2, h3, h4, h5, h6, p { margin: 0; } h1 { font-weight: 600; } /* top ================================ */ .top-wrapper { max-width: 1200px; min-width: 920px; display: flex; justify-content: center; align-items: center; margin: 0 auto; padding: 60px; } .top-detail { width: 36%; min-width: 320px; margin-top: -40px; } .top-detail .subtitle { font-size: 14px; font-weight: 600; margin-bottom: 4px; } .top-detail .title { font-size: 54px; line-height: 66px; letter-spacing: 2px; margin-bottom: 24px; } .top-detail .description { font-size: 14px; line-height: 28px; letter-spacing: 0.5px; margin-bottom: 40px; } .top-detail .index-button { width: 184px; height: 48px; text-align: center; line-height: 45px; font-weight: 600; color: #42cea9;; background-color: #ffffff; border: 2px solid #58d2b2; border-radius: 2px; } .top-detail .index-button:hover { color: #ffffff; background-color: #58d2b2; } .index-button { cursor: pointer; } .top-image { width: 64%; text-align: center; overflow: hidden; } .top-image img { width: 88%; } /* header ================================ */ header { height: 56px; background-color: #ffffff; border-bottom: 1px solid #f0f4f9; } .header-logo { margin-left: 56px; font-weight: 600; font-size: 20px; line-height: 56px; color: #6c7686; display: inline; } .header-logo:hover { color: #58d2b2; } /* container ================================ */ .container { width: 80%; min-width: 360px; max-width: 720px; margin: 0 auto; margin-top: 56px; } .container-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .container-header h1 { font-size: 24px; } /* index ================================ */ .table-head { display: flex; background-color: #b7cadc; border-radius: 2px 2px 0 0; height: 44px; font-size: 16px; line-height: 46px; color: #ffffff; } .id-column { width: 72px; text-align: center; } .table-body { background-color: #ffffff; } .table-body li { height: 72px; border: 1px solid #f0f4f9; border-top: none; line-height: 74px; display: flex; } .table-body .id-column { font-size: 16px; color: #bac6d3; } .table-body .name-column { font-size: 14px; font-weight: 500; color: #8491a5; }top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <!-- CSSファイルを読み込んでください --> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <a class="index-button">一覧を見る</a> </div> <div class="top-image"> <!-- 画像ファイルを読み込んでください --> <img src="/images/top.png"> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして一覧画面の作成
・
ndex.ejs
というファイルで一覧画面を作成する。
/index
のGETをapp.jsに実装する。
app.jsconst express = require('express'); const app = express(); app.use(express.static('public')); app.get('/', (req, res) => { res.render('hello.ejs'); }); app.get('/top', (req, res) => { res.render('top.ejs'); }); // 一覧画面を表示するルーティングを作成してください app.get('/index', (req, res) => { res.render('index.ejs'); }); app.listen(3000);index.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <header> <a class="header-logo">LIST APP</a> </header> <div class="container"> <div class="container-header"> <h1>買い物リスト</h1> </div> <div class="index-table-wrapper"> <div class="table-head"> <span class="id-column">ID</span> <span>買うもの</span> </div> <ul class="table-body"> <li> <span class="id-column">1</span> <span class="name-column">じゃがいも</span> </li> <li> <span class="id-column">2</span> <span class="name-column">にんじん</span> </li> <li> <span class="id-column">3</span> <span class="name-column">たまねぎ</span> </li> </ul> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして
EJSを使って値を表示しよう
・
ejs
とは「EJSは、HTMLとJavaScriptのコード両方を記述できるNode.jsのパッケージ」らしい。
Embedded javaScript
HTMLの中にJavaScriptを埋め込む
らしい。ReactはJSにHTMLを埋め込むイメージでしたよね。
・なんとnpm install ejs
を最初にやる必要があったらしい。
紛らわしい。なぜその手順を最初に解説しなかったのか・・・。・JavaScritpを埋め込むには
<% %>
または<%= %>
を使用するらしい。Rubyと一緒かな?forEachを使ったHTMLの表示
・
ejs
上でforEachできる。
ただし、forEachの閉じは<% });%>
とかなり独特。ページ間リンク
・リンクは
a
タグのhref=""のところにパスを記載する。app.js
const express = require('express'); const app = express(); app.use(express.static('public')); // 下記のルーティングを削除してください // 削除ここまで // ルートURLで表示されるように変更してください app.get('/', (req, res) => { res.render('top.ejs'); }); app.get('/index', (req, res) => { res.render('index.ejs'); }); app.listen(3000);index.js
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <header> <!-- href属性を追加してください --> <a class="header-logo" href="/" >LIST APP</a> </header> <div class="container"> <div class="container-header"> <h1>買い物リスト</h1> </div> <div class="index-table-wrapper"> <div class="table-head"> <span class="id-column">ID</span> <span>買うもの</span> </div> <% const items = [ {id: 1, name: 'じゃがいも'}, {id: 2, name: 'にんじん'}, {id: 3, name: 'たまねぎ'} ]; %> <ul class="table-body"> <% items.forEach((item) => { %> <li> <span class="id-column"><%= item.id %></span> <span class="name-column"><%= item.name %></span> </li> <% }); %> </ul> </div> </div> </body> </html>top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <!-- href属性を追加してください --> <a class="index-button" href="/index" >一覧を見る</a> </div> <div class="top-image"> <img src="/images/top.png"> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして
感想
・比較的簡単にWebが作れました。
DBから引っ張ってくるところとかはおそらく有料の上級編でやっているんだろうなぁ・・・。
・Node.jsに言えたことではないが、今まで無料レッスンやってきた言語のWeb系のデプロイってどうやるんだろうw今回でProgate無料版はすべてこなしました。
いつも書いているように、無料版なので、基礎や基本的なことしかやらないので、即何かアプリを作れるかと言ったら、この内容だけじゃ難しいですが、他無料サイトをみながらアプリ作成を始めてみる際にはこのレッスンの経験が少しは生きてくると思いました。次回はReactのチュートリアルの三目並べゲームをやってみたいと思います。
- 投稿日:2020-03-22T19:42:06+09:00
Progate無料版をやってみる【Node.js】
前回に引き続きProgate無料レッスンをやっていこうと思います。
今回はNode.jsです。
Progateの無料版のレッスンはこれで終わります。
以前のレッスンで既にインストール済みです。Node.js
Expressの導入
・ExpressとはNode.jsでWebアプリを開発するためのフレームワーク。
RubyでいうところのRailsになんでしょうね。C#でいうところのASP.NETみたいな。
・おなじみのパッケージ。便利な機能、メソッドが揃った塊、ライブラリの事。
・npm
コマンドでExpressをインストールする。
npm
とはNode Package Manager
その名の通り、Node.jsのパッケージを管理するツール。これを使ってパッケージを取得する。環境
最近こればっかりですが、VSCode使っていきます。適当なデイレトリを作成し
VSVodeで開きます。
ターミナルを開きます。
まずinitします。npm init
package name: (node)
と聞かれた作成するpackage.jsonの名前をいれます。任意な値。nodeにしました。次に、以下を実行してExpressをインストールします。
npm install expressProgateのレッスンにもどります。
Progateのディレクトリ構成を再現します。
C:\job\Node │ app.js │ package-lock.json │ package.json │ ├─node_modules └─public └─imagesapp.js等の中身もコピペします。
app.js
const express = require('express'); const app = express();サーバーの起動
・
app.listen(3000);
と記述することで、ポート3000のhttp通信を受けつけることになるらしい。app.js
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.render('hello.ejs'); }); // サーバーを起動するコードを貼り付けてください app.listen(3000);getのところは、TOP
/
にGET
リクエストがあった場合にhello.ejs
をレンダリングする意味だと思います。
ejs
ってなんすかwProgateを真似すると、Viewsディレクトリが新たにできていて、その中に
hello.ejs
があります。
hello.ejs<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello World</title> <script src="/send_url.js"></script> </head> <body> <h1>Hello World</h1> </body> </html>
/send_url.js
ってなんだ?w
ターミナルでnode app.jsと打って実行します。
http://localhost:3000
にアクセスすると以下のエラーとなった
package.jsonの内容がちがったから、そのせいかな?
一緒にしてみる。package.json
{ "name": "nodejs_lesson", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "eslint": "eslint ./", "start": "nodemon -r './.module' ./app.js" }, "author": "Progate", "license": "ISC", "dependencies": { "ejs": "^2.6.1", "express": "^4.16.4" }, "devDependencies": { "nodemon": "^1.18.10" } }でも同じエラー。
あ、書き換えたpackage.jsonを適用するのかな?と思いnpm updateこれで、package.jsonに記載した
"ejs": "^2.6.1"
が適用されずはず・・・。実行後に
http://localhost:3000
にアクセス。
表示できました!ページの表示の仕組み
・見た目部分には
ejs
という形式のファイルを使い、views
ディレクトリの下に配置するらしい。HTMLと同じと思えとのこと。演習
・新たにtop.ejs
が追加になる。app.js
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.render('hello.ejs'); }); // トップ画面を表示するルーティングを作成してください app.get('/top', (req, res) => { res.render('top.ejs'); }); app.listen(3000);top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <a class="index-button">一覧を見る</a> </div> <div class="top-image"> </div> </div> </body> </html>
npm app.js
してからhttp://localhost:3000/top
にアクセス
CSSの適用と画像の表示
・「Expressでは、CSSや画像などのファイルがどこに置かれているかを指定する必要があります」らしい。
publicにある。
・app.jsでapp.use(express.static('public'));
を行う必要がある。
・Progateの説明の通り、style.css
を追加する。top.ejsで読み込む。app.js
const express = require('express'); const app = express(); // CSSや画像ファイルを置くフォルダを指定するコードを貼り付けてください app.use(express.static('public')); app.get('/', (req, res) => { res.render('hello.ejs'); }); app.get('/top', (req, res) => { res.render('top.ejs'); }); app.listen(3000);public/css/style.css
/* reset ================================ */ * { box-sizing: border-box; } html { font-size: 100%; font-family: 'Hiragino Sans', sans-serif; line-height: 1.7; letter-spacing: 1px; } body { margin: 0; background-color: #f6faff; color: #6c7686; } ul, li { list-style-type: none; padding: 0; margin: 0; } a { display: block; text-decoration: none; color: #2d3133; font-size: 14px; } a:hover { transition: all 0.3s ease; } h1, h2, h3, h4, h5, h6, p { margin: 0; } h1 { font-weight: 600; } /* top ================================ */ .top-wrapper { max-width: 1200px; min-width: 920px; display: flex; justify-content: center; align-items: center; margin: 0 auto; padding: 60px; } .top-detail { width: 36%; min-width: 320px; margin-top: -40px; } .top-detail .subtitle { font-size: 14px; font-weight: 600; margin-bottom: 4px; } .top-detail .title { font-size: 54px; line-height: 66px; letter-spacing: 2px; margin-bottom: 24px; } .top-detail .description { font-size: 14px; line-height: 28px; letter-spacing: 0.5px; margin-bottom: 40px; } .top-detail .index-button { width: 184px; height: 48px; text-align: center; line-height: 45px; font-weight: 600; color: #42cea9;; background-color: #ffffff; border: 2px solid #58d2b2; border-radius: 2px; } .top-detail .index-button:hover { color: #ffffff; background-color: #58d2b2; } .index-button { cursor: pointer; } .top-image { width: 64%; text-align: center; overflow: hidden; } .top-image img { width: 88%; } /* header ================================ */ header { height: 56px; background-color: #ffffff; border-bottom: 1px solid #f0f4f9; } .header-logo { margin-left: 56px; font-weight: 600; font-size: 20px; line-height: 56px; color: #6c7686; display: inline; } .header-logo:hover { color: #58d2b2; } /* container ================================ */ .container { width: 80%; min-width: 360px; max-width: 720px; margin: 0 auto; margin-top: 56px; } .container-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .container-header h1 { font-size: 24px; } /* index ================================ */ .table-head { display: flex; background-color: #b7cadc; border-radius: 2px 2px 0 0; height: 44px; font-size: 16px; line-height: 46px; color: #ffffff; } .id-column { width: 72px; text-align: center; } .table-body { background-color: #ffffff; } .table-body li { height: 72px; border: 1px solid #f0f4f9; border-top: none; line-height: 74px; display: flex; } .table-body .id-column { font-size: 16px; color: #bac6d3; } .table-body .name-column { font-size: 14px; font-weight: 500; color: #8491a5; }top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <!-- CSSファイルを読み込んでください --> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <a class="index-button">一覧を見る</a> </div> <div class="top-image"> <!-- 画像ファイルを読み込んでください --> <img src="/images/top.png"> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして一覧画面の作成
・
ndex.ejs
というファイルで一覧画面を作成する。
/index
のGETをapp.jsに実装する。
app.jsconst express = require('express'); const app = express(); app.use(express.static('public')); app.get('/', (req, res) => { res.render('hello.ejs'); }); app.get('/top', (req, res) => { res.render('top.ejs'); }); // 一覧画面を表示するルーティングを作成してください app.get('/index', (req, res) => { res.render('index.ejs'); }); app.listen(3000);index.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <header> <a class="header-logo">LIST APP</a> </header> <div class="container"> <div class="container-header"> <h1>買い物リスト</h1> </div> <div class="index-table-wrapper"> <div class="table-head"> <span class="id-column">ID</span> <span>買うもの</span> </div> <ul class="table-body"> <li> <span class="id-column">1</span> <span class="name-column">じゃがいも</span> </li> <li> <span class="id-column">2</span> <span class="name-column">にんじん</span> </li> <li> <span class="id-column">3</span> <span class="name-column">たまねぎ</span> </li> </ul> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして
EJSを使って値を表示しよう
・
ejs
とは「EJSは、HTMLとJavaScriptのコード両方を記述できるNode.jsのパッケージ」らしい。
Embedded javaScript
HTMLの中にJavaScriptを埋め込む
らしい。ReactはJSにHTMLを埋め込むイメージでしたよね。
・なんとnpm install ejs
を最初にやる必要があったらしい。
紛らわしい。なぜその手順を最初に解説しなかったのか・・・。・JavaScritpを埋め込むには
<% %>
または<%= %>
を使用するらしい。Rubyと一緒かな?forEachを使ったHTMLの表示
・
ejs
上でforEachできる。
ただし、forEachの閉じは<% });%>
とかなり独特。ページ間リンク
・リンクは
a
タグのhref=""のところにパスを記載する。app.js
const express = require('express'); const app = express(); app.use(express.static('public')); // 下記のルーティングを削除してください // 削除ここまで // ルートURLで表示されるように変更してください app.get('/', (req, res) => { res.render('top.ejs'); }); app.get('/index', (req, res) => { res.render('index.ejs'); }); app.listen(3000);index.js
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <header> <!-- href属性を追加してください --> <a class="header-logo" href="/" >LIST APP</a> </header> <div class="container"> <div class="container-header"> <h1>買い物リスト</h1> </div> <div class="index-table-wrapper"> <div class="table-head"> <span class="id-column">ID</span> <span>買うもの</span> </div> <% const items = [ {id: 1, name: 'じゃがいも'}, {id: 2, name: 'にんじん'}, {id: 3, name: 'たまねぎ'} ]; %> <ul class="table-body"> <% items.forEach((item) => { %> <li> <span class="id-column"><%= item.id %></span> <span class="name-column"><%= item.name %></span> </li> <% }); %> </ul> </div> </div> </body> </html>top.ejs
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LIST APP</title> <link rel="stylesheet" href="/css/style.css"> <script src="/send_url.js"></script> </head> <body> <div class="top-wrapper"> <div class="top-detail"> <h2 class="subtitle">買い物リストアプリ</h2> <h1 class="title">LIST APP</h1> <p class="description"> LIST APPは、買い物をリストアップするサービスです。 <br> 買いたいものをリストに追加してみましょう。 </p> <!-- href属性を追加してください --> <a class="index-button" href="/index" >一覧を見る</a> </div> <div class="top-image"> <img src="/images/top.png"> </div> </div> </body> </html>
http://localhost:3000/top
にアクセスして
感想
・比較的簡単にWebが作れました。
DBから引っ張ってくるところとかはおそらく有料の上級編でやっているんだろうなぁ・・・。
・Node.jsに言えたことではないが、今まで無料レッスンやってきた言語のWeb系のデプロイってどうやるんだろうw今回でProgate無料版はすべてこなしました。
いつも書いているように、無料版なので、基礎や基本的なことしかやらないので、即何かアプリを作れるかと言ったら、この内容だけじゃ難しいですが、他無料サイトをみながらアプリ作成を始めてみる際にはこのレッスンの経験が少しは生きてくると思いました。次回はReactのチュートリアルの三目並べゲームをやってみたいと思います。
- 投稿日:2020-03-22T18:40:58+09:00
TypeORMのconnection設定はormconfig.jsに書くのがおすすめ
はじめに
TypeORMのcreateConnectionメソッドを呼ぶ際の設定値は、色々な指定方法があります。
色々あって迷っちゃったので、整理して考えた結果、ormconfig.jsに書くのが分かりやすいのではという結論に至りました。createConnectionメソッドの引数として直接渡す方法は避けたかった
createConnectionメソッドでは、引数としてconnectionの設定値を直接渡す方法があります。
https://typeorm.io/#/connection/creating-a-new-connection
メソッド引数として直接渡す例(公式ドキュメントの引用)import {createConnection, Connection} from "typeorm"; const connection = await createConnection({ type: "mysql", host: "localhost", port: 3306, username: "test", password: "test", database: "test" });バックエンドのアプリケーションにおいて、createConnectionを呼ぶのは大抵の場合、サーバー起動時に一回だけでしょう。そのため、一見するとこの方法でもさほど問題なさそうに思えます。
ところがTypeORMは、バックエンドアプリケーション用の本番コードからだけでなく、何らかのテストコードからとか、DBマイグレーション用のCLIコマンドから呼ばれる場合もあるはずです。
それらを視野に入れると、createConnectionの引数として直接渡すだけではカバーしにくい場面がでてきそうです。似たような設定を何箇所かに重複して書く羽目になるかもしれません。引数として直接渡す以外の方法は色々ある
では他の方法はというと、大別すると2種類があります。このあと紹介するそれらの方法で設定した上で、引数なしでcreateConnectionメソッドを呼べば、その設定が参照されます(Creating a new connectionの節の後半で、そう説明されています)。
環境変数TYPEORM_XXXを設定する
1つ目は、何らかの手段によって、所定の名前の環境変数を設定する方法です。
TYPEORM_CONNECTION
やTYPEORM_HOST
など、TYPEORM_XXX
という名前の環境変数を設定しておくと、TypeORMはその値を参照します。参照される環境変数名は、以下のURLにまとめられています。https://typeorm.io/#/using-ormconfig/using-environment-variables
この方法の亜種として、環境変数を設定する代わりに、ormconfig.envというファイルにそれらの設定を書く方法もあります。
ormconfigファイルを作る
2つ目は、ormconfig.xxx(ただし、xxx ≠ env)というファイルをpackage.jsonと同じ階層に置き、そこに設定を書く方法です。拡張子はjs、json、ymlなどから選べます。
jsにおける例(公式ドキュメントの引用)module.exports = { "type": "mysql", "host": "localhost", "port": 3306, "username": "test", "password": "test", "database": "test" }環境変数TYPEORM_XXXとormconfigの併用はできない
下記のURLで述べられている通り、上記2種類の設定方法を併用することはできません。環境変数TYPEORM_XXXが設定されていると、ormconfigファイルは無視されます。
https://typeorm.io/#/using-ormconfig/which-configuration-file-is-used-by-typeorm
TypeORMの設定値の中には、環境変数で指定したいものもあるでしょうし(例えばDBのパスワード)、分かりやすくどこかにハードコードしたいものもあるでしょう。ところがあいにく、環境変数TYPEORM_XXXとormconfigファイルの併用はできません。
そこで
そこで、以下のようにすればちょうど良い落とし所になるのではと考えました。
- ormconfig.jsファイルを用意する。
- ormconfig.jsの中で必要に応じて、環境変数を参照する。
この時、ormconfig.jsに書く環境変数名はTYPEORM_XXXではなく、TypeORMが予約していない何らかの独自の名前にします。そうすれば、「環境変数TYPEORM_XXXが設定されていると、ormconfigファイルは無視される」という制約を気にせず、柔軟に設定をかけるようになります。
jsファイルなので、環境変数の値に応じたちょっとした分岐を書きやすい利点もあります。まとめ
TypeORMは、バックエンドアプリケーション用の本番コードからだけでなく、何らかのテストコードからとか、DBマイグレーション用のCLIコマンドから呼ばれる場合もあるので、1個の設定用ファイルにまとめて書いておけば、どこから呼んだ場合でも対応できます。
そして、設定用ファイルの種類としてormconfig.jsを使えば、jsファイルの中で環境変数(TYPEORM_XXXでない独自名)を参照させたり、ちょっとした分岐を書いたりと、柔軟に設定を書くことができます。
その環境変数はどこでどう設定するんかっていう点は残りますが、それはTypeORMの専用知識とは切り離した汎用的な問題として、独立して検討しやすいでしよう。また、TypeORM設定の入り口がormconfig.jsという一箇所に集約されるので、(jsファイルの中で、どこかで設定されている環境変数を参照しているとはいえ、)見通しもそこそこ良くなります。
- 投稿日:2020-03-22T17:04:59+09:00
『Node.js 超入門』の express-validation を最新の仕様に修正する
概要
Node.js 超入門(第2版) を読んでいたところ、バリデーションの箇所が本の通り書いているにも関わらずエラーが発生。 正誤表 を確認したところ、以下のような説明がありました。
本書で使用している Express Validator は、現在 ver.6 となり、仕様が変更されているため、本書の記述の通りでは正常に動作しなくなっています。
ver.5 にバージョンダウンすることでサンプルコードのまま実行することが出来たのですが、折角なので最新バージョンに修正して実行をしてみました。
本記事では、express-validator公式ドキュメントを参考に行った修正内容について紹介したいと思います。修正内容
サンプルコード(ver.5 の書き方)
- P.334~335 リスト6-4 より、修正の必要があるPOST時の処理について抜粋
※修正後と形式を統一するためフォーマッタで一部書き方等を修正してますhello.jsrouter.post("/add", (req, res, next) => { req.check("name", "NAME は必ず入力して下さい。").notEmpty(); req.check("mail", "MAIL はメールアドレスを記入して下さい。").isEmail(); req.check("age", "AGE は年齢(整数)を入力下さい。").isInt(); req.getValidationResult().then(result => { if (!result.isEmpty()) { var re = '<ul class="error">'; var result_arr = result.array(); for (var n in result_arr) { re += "<li>" + result_arr[n].msg + "</li>"; } re += "</ul>"; var data = { title: "Hello/Add", content: re, form: req.body }; res.render("hello/add", data); } else { var nm = req.body.name; var ml = req.body.mail; var ag = req.body.age; var data = { name: nm, mail: ml, age: ag }; var connection = mysql.createConnection(mysql_setting); connection.connect(); connection.query("insert into mydata set ?", data, function( error, results, fields ) { res.redirect("/hello"); }); connection.end(); } }); });修正後コード(ver.6 の書き方)
- express-validationの最新バージョン(記事作成時は6.4.0)で実行できるようPOST処理を修正
※バリデーション設定箇所以外にも今時のJavaScriptの書き方に変更している箇所もあります(varでなくconstかletで変数を宣言するなど)hello.jsconst { check, validationResult } = require("express-validator"); router.post( "/add", [ check("name") .not() .isEmpty() .withMessage("NAME は必ず入力して下さい。"), check("mail") .isEmail() .withMessage("MAIL はメールアドレスを記入して下さい。"), check("age") .isInt() .withMessage("AGE は年齢(整数)を入力して下さい。") ], (req, res, next) => { const results = validationResult(req); if (!results.isEmpty()) { let re = "<ul class='error'>"; const result_arr = results.array(); for (const err of result_arr) { re += `<li>${err.msg}</li>`; } re += "</ul>"; const data = { title: "Hello/Add", content: re, form: req.body }; res.render("hello/add", data); } else { const name = req.body.name; const mail = req.body.mail; const age = req.body.age; const data = { name, mail, age }; const connection = mysql.createConnection(mysql_setting); connection.connect(); connection.query( "INSERT INTO mydata SET ?", data, (error, results, fields) => { if (error === null) { res.redirect("/hello"); } } ); connection.end(); } } );修正概要
今回でexpress-validationを使った処理に関しては以下の部分を修正しています
require
によるモジュールのロードをapp.js
ではなくhello.js
の冒頭で行う
- サンプルの通り
app.js
で宣言した場合には『TypeError: check is not a function』が発生するため変更- エラー原因は調査しましたがわからなかったので、ご存知の方がいましたらコメントで教えていただけたら幸いです
check
内容をpost
メソッドの第2引数に記載- ver.5 ではエラー情報を
req.getValidationResult().then()
でresult
を引数としてコールバック関数で処理していたが、ver.6ではvalidationResult(req)
を定数result
に代入し、関数の中でその値を使って処理notEmpty()
はなくなっているので、not().isEmpty()
のように宣言- エラーメッセージは
withMessage()
をメソッドチェーンにして使用し設定まとめ
以上のように修正することで、記事作成時の最新バージョン(ver.6.4.0)のexpress-validatorでもバリデーションを実行することができました。
よかったら参考にしてみて下さい。
- 投稿日:2020-03-22T16:04:02+09:00
[Visual Studio Code] [MacOS] .nvmrcで指定したバージョンに自動で切り替えてプロジェクトをスタートする
複数の Node.js プロジェクトに参加していると、利用すべき Node のバージョンがプロジェクト毎に異なる場合があって、毎回手動で切り替えるのは大変面倒なので自動化します。
動作確認環境
- MacOS
- Visual Studio Code
にて動作を確認しております。Mac かつ VSCode で開発をしていて、ビルドなども VSCode 上のターミナルで行なっている方は参考になると思います。
ロードマップ
- nvmのインストール
- Visual Studio Code のターミナルをzshに設定する
- .zshrc を作成、または編集する
- 自動バージョン切り替えを実行したいプロジェクトで .nvmrc を作成する
1.nvmのインストール
日本語の参考記事がたくさんありますのでそちらを参照してください。
nvm use <バージョン>
コマンドでいくつかの node バージョンを切り替えられるようになればOKです。
2.Visual Studio Code のターミナルをzshに設定する
まずは現在の VSCode のターミナルのシェルが何か、確認します。
青枠部分がzshでない場合は設定で変更します。Mac 自体が2019年に、デフォルトの処理を bash から zsh に切り替えているので、基本的には VSCode もそれに沿う形で問題ないはずです。既に bash でいろいろ設定やってるよという方は zsh に切り替えることの影響を考慮する必要があります。
⌘ + ,
で設定パネルを開き、
Terminal › Integrated › Automation Shell: Osx
の項目で Edit in settings.jsをクリックします。
"terminal.integrated.shell.osx": "/bin/zsh"
terminal.integrated.shell.osx の値を上記のようにします。基本的にこちらの値で問題ないと思いますが、環境によって、zshがインストールされていない、場所が違うなどあるかもしれませんのでご確認ください。編集したら改めて VSCode 上のターミナルを確認し、zsh となっていればOKです。
.zshrc を作成、または編集する
基本これで良いはず。
$ vim .zshrcsource ~/.nvm/nvm.sh # place this after nvm initialization! autoload -U add-zsh-hook load-nvmrc() { if [[ -f .nvmrc && -r .nvmrc ]]; then nvm use elif [[ $(nvm version) != $(nvm version default) ]]; then echo "Reverting to nvm default version" nvm use default fi } add-zsh-hook chpwd load-nvmrc load-nvmrc既に .zshrc ファイルが存在している場合は既存の設定内容に影響がないか注意が必要です。また、1行目の nvm のパスも環境によっては違うかもしれません。
4.自動バージョン切り替えを実行したいプロジェクトで .nvmrc を作成する
ここまでくればただただバージョン番号が書かれた.nvmrcファイルがプロジェクトディレクトリの直下に存在していれば、プロジェクトを開いた際にnvmによるバージョン切り替えを行なってくれます。バージョン番号指定ではなく
lts/*
のように安定バージョンの最新というような書き方もできます。(が、該当バージョンをnvmでインストール済みでないと動かないと思います。私は常にバージョン番号で指定しているので未確認です。).nvmrc はコマンドラインでサクッと作成してしまいましょう。
$ echo "8.13.0" > .nvmrc #番号指定 $ echo "lts/*" > .nvmrc #最新バージョン以上で設定完了です。VSCode で該当プロジェクトを開き、VSCode 上のターミナルを立ち上げれば .nvmrc で指定したバージョンに切り替えたことを示すメッセージがターミナルで確認できるはずです。
また、複数でプロジェクトを進める際に node のバージョンをバシッと統一するときもこの形がスマートだと思います。
参考リンク
https://qiita.com/ysd_marrrr/items/e58df8dfd509b25ff9c9
https://medium.com/fbdevclagos/updating-visual-studio-code-default-terminal-shell-from-bash-to-zsh-711c40d6f8dc
https://medium.com/@kinduff/automatic-version-switch-for-nvm-ff9e00ae67f3
- 投稿日:2020-03-22T15:33:17+09:00
WebSocket の負荷テストは Artillery でシュッと簡単に実行しよう
Artillery は yaml ファイルに宣言的にシナリオを記述し、シンプルなインタフェースで負荷をかけることができる Nodejs 製の負荷テストツールです。
本記事では Artillery を使用して簡単に WebSocket サーバの負荷テストを実行する方法を紹介します。最小構成の WebSocket サーバ
まずはじめに WebSocket サーバを実装しましょう。今回は Node.js を使用します。
必要最小限の機能だけを提供します。ws ライブラリを使用して簡単に実装しましょう。server.jsconst WebSocket = require("ws"); const wss = new WebSocket.Server({ port: 3000 }, () => { console.log("server is now listening localhost:3000"); }); let connections = []; wss.on("connection", ws => { connections.push(ws); console.log(`new connection established. connections: ${connections.length}`); ws.on("close", () => { console.log(`connection closeed: ${connections.length}`); connections = connections.filter((conn, i) => conn !== ws); }); ws.on("message", message => { broadcast(JSON.stringify(message)); }); }); const broadcast = message => { connections.forEach((con, i) => { con.send(message); }); };起動して以下のメッセージが表示されれば準備完了です。
$ node server.js server is now listening localhost:3000
wscat で接続を確認する
サーバを起動したらまず wscat を使用して動作の確認をしましょう。wscat は npm でインストールできます。
$ npm install -g wscatWebSocket サーバを起動し、wscat で接続したら任意のメッセージを送信してみましょう。1つのクライアントからの送信を受けて、他のクライアントへ broadcast していることがわかります。
Artillery を使用して負荷テストを実行する
さて、ようやく本題です。Artillery を使用して負荷テストをかけてみましょう。
最小限のシナリオファイルのサンプルです。シナリオファイルはsenario.yml
のような名前をつけておきます。senario.yamlconfig: target: "ws://localhost:3000" phases: - duration: 20 arrivalRate: 10 scenarios: - engine: "ws" flow: - send: "hello"以下、コマンドで実行します。
$ artillery run senario.yml
アクティブなコネクション数を調整する
実際に WebSocket を用いたアプリケーションでは、常に多くのコネクションが張られていることが一般的です。上記のシナリオでは hello というメッセージを送ったらすぐにコネクションを切断してしまうので、常時アクティブなコネクションが少ない状態であまり現実的ではありません。まずは、
think
を指定してアクティブなコネクション数が増えるように調整しましょう。また、同じメッセージを繰り返し送信するloop
も指定できます。senario.yamlscenarios: - engine: "ws" flow: - send: "hello" - think: 1 # pause for 1 second - loop: - send: "world" count: 5オブジェクトの送信に対応する
さて先ほどまでは string 形式のデータだけに限定していましたが、
{"name":"john", "age":24}
のようにオブジェクト形式で送信する方が良いこともあるでしょう。以下のように記述すれば、送信時に Stringify してくれます。senario.yamlscenarios: - engine: "ws" flow: # the following will be stringified and sent as '{"name":"john","age":24}' - send: name: "john" age: 24カスタムコードを使用してタイムスタンプを付与する
また、送信したタイムスタンプを付与したいこともあります。このようなケースに対応するためにはカスタムコードを使用して柔軟に値を差し込むことができます。
senario.yamlconfig: target: "ws://localhost:3000" processor: "./custom.js" scenarios: - engine: "ws" flow: # custom code for timestanp - function: "createTimestampedObject" - send: "{{ data }}"非常にシンプルに記述し、シュッと実装することができました。Artillery は WebSocket だけではなく、HTTPのプロトコルもサポートしています。本記事は公式ドキュメントから参照していますので、詳細に理解されたい方は一度ドキュメントに目を通してみるのも良いでしょう。
また、CircleCIで継続的に負荷テストを実行するTipsをこちらの記事で紹介していますのでぜひご参照ください。
- 投稿日:2020-03-22T13:52:37+09:00
arduino + leapmotion でmidi ドラム Play!
ドラムマシーンを足で演奏することを目指しています。
手で演奏するプロトタイプを作成しました。・arduino uno
・SparkFun midiシールド
・leapmotion
・node.js
・CASIO キーボード CTK-530leapmotionとarduinoでシリアル通信
参考サイト:
ArduinoとNode.jsでシリアル通信で文字列を送受信するスクリプト
ArduinoとLeapmotionのシリアル接続まずはleapmotion側(node.js)
準備物は↑を参照願います。leap-arduino.js"use strict" const serialport = require('serialport'); // arduinoポート名指定(arduino IDEから取得) var portName = '/dev/cu.usbmodem1421'; /* jsライブラリ読込 */ var Leap = require("leapjs"); var five = require('johnny-five'); var yPosi = 0; //座標 var G_KICK_TIME = new Date();//センサーキック時刻 var C_WAITE_TIME = 100; //ミリ秒 //Leap Motionコントローラー作成 var controller = new Leap.Controller(); //leapmotionと接続開始 controller.connect(); //手を認識 controller.on('hand', function (gesture,e) { //y軸取得 yPosi = gesture.palmPosition[1]; yPosi = parseInt(yPosi); var ss = new Date(); //前回のarduino送信からの時間比較 if(ss.getTime() - G_KICK_TIME.getTime() >= C_WAITE_TIME ){ //C_WAITE_TIME経過した場合 //arduino通信発生時刻 G_KICK_TIME = new Date(); console.log("ON"); //arduinoへ送信する関数 write(yPosi); } }); const Readline = serialport.parsers.Readline; const parser = new Readline(); const spp = new serialport(portName,{ baudRate: 31250,//midiのボーレートが31250 dataBits: 8, parity: 'none', stopBits: 1, flowControl: false, parser: parser }); //シリアル通信開始 spp.on('open', function () { console.log('Serial open.'); }); //arduinoから受信した場合の処理(今回は未使用) //spp.on('data', function (data) { // //console.log('spp.on-data:' + data); //}); //arduinoへ送信 function write(data) { //y軸座標の範囲で値を設定; var sendData; if (data > 0 && data <= 160){ //スネアドラム sendData = 'a'; } else if (data > 160 && data <= 200){ //ハイハットclose sendData = 'b'; } else if (data > 200 && data <= 250){ //ハイハットopen sendData = 'c'; } else { //上記以外 sendData = '0'; } data = sendData; //送信データ表示 console.log('Mac:' + data); //arduinoへ値送信! spp.write(new Buffer.from(data), function(err, results) { if(err) { //エラーメッセージ表示 console.log('Err: ' + err); } }); }続いてarduino側です。
参考サイト
Arduino MIDI Library の使い方手をかざすとC_WAITE_TIMEの間隔でCASIOキーボードのドラムを鳴らします。
//MIDIライブラリ使用のためのヘッダファイル読み込み #include <MIDI.h> // MIDIクラスのインスタンスとして"MIDI"を生成する。 MIDI_CREATE_DEFAULT_INSTANCE(); #define LED 13 int recieveByte = 0; String bufferStr = ""; String okStr = "OK"; //送信ONフラグ const bool C_ON = true; const bool C_OFF = false; //ノート情報 const int C_NOTE_VEROCITY = 40; const int C_NOTE_CHANNEL = 1; bool bLedState = false; //受信状態 true:on false:off int pitchNo = 0; void setup() { Serial.begin(31250); //midiのボーレートが31250 MIDI.begin(); // MIDIインスタンスの初期化 } void loop() { bufferStr = ""; while (Serial.available() > 0) { recieveByte = Serial.read(); if (recieveByte == (int)'\n') break; bufferStr.concat((char)recieveByte); } //受信信号実行中の場合無視して次へ if(bLedState == C_OFF){ //受信データによりCASIOキーボードへMIDI送信 if (bufferStr.length() > 0) { if (bufferStr == "a") { bLedState = C_ON; pitchNo = 38;//スネア } else if (String(bufferStr) == "b") { bLedState = C_ON; pitchNo = 44;//ハイハットclose } else if (String(bufferStr) == "c") { bLedState = C_ON; pitchNo = 46;//ハイハットopen } else { bLedState = C_OFF; pitchNo = 36;//バスドラ } //ノートオン(pitch, velocity, channel) MIDI.sendNoteOn(pitchNo, C_NOTE_VEROCITY, C_NOTE_CHANNEL); //待機後信号受付状態にする bLedState = C_OFF; MIDI.sendNoteOff(pitchNo, C_NOTE_VEROCITY, C_NOTE_CHANNEL); } } }MIDIのボーレートの既定値が31250のため、シリアル通信もそれに合わせています。
そうしないとarduino側で受信データが文字化けしてしまいます。
これでハマりました。スイッチサイエンスで距離計測センサーを購入したので、届き次第leapmotionからこのセンサーに変更します。
記事は着手次第アップします。
- 投稿日:2020-03-22T11:35:25+09:00
Node.js+Express+Passportでログイン認証をしたい
はじめに
「Node.jsってどんなもんなんだろう?」ってところから始まり。
↓
「へぇ〜APIとか簡単にできるじゃん」となり。
↓
「ログイン認証とかも割と簡単なんじゃね」と思ったのでやってみました。環境
- macOS Mojave
Express
npm
を使ってExpressをインストールする。
entry pointはapp.js
に設定する。$ mkdir myapp $ cd myapp $ npm init $ npm install expressmyappに
app.js
を作成し、以下を実装する。app.jsconst express = require('express') const app = express() app.get('/', (req, res) => { res.send('Hello World') }) app.listen(3000, () => { console.log('Listening on prot 3000') })普通に
node app.js
で起動しても良いが、変更に対して自動的に起動するようにしてほしいのでnodemon
をインストールする。
起動したら、http://localhost:3000
にアクセスし期待通りの動きをしているか確認する。$ npm install nodemon -g $ npx nodemon app.js [nodemon] starting `node app.js` Listening on prot 3000Passport
ログイン認証に必要なものをインストールします。
(詳しく説明しませんが、ググれば大丈夫)$ npm install body-parser $ npm install cookie-parser $ npm install express-session $ npm install passport $ npm install passport-local $ npm install connect-ensure-login
public
フォルダを作成し、login.html
、ok.html
、ng.html
を作成するapp.jsconst express = require('express') const app = express() const path = require('path') const session = require('express-session') const passport = require('passport') const bodyParser = require('body-parser') const cookieParser = require('cookie-parser') const LocalStrategy = require('passport-local').Strategy; app.use(express.static(path.join(__dirname, 'public'))) app.use(cookieParser()) app.use(bodyParser.urlencoded({ extended: true })) app.use(session({ secret: 'secret', resave: false, saveUninitialized: false, })) app.use(passport.initialize()) app.use(passport.session()) passport.use(new LocalStrategy((username, password, done) => { if (username !== 'user' || password !== 'passwd') { return // ログイン失敗 } return done(null, username) // ログイン成功 })) passport.serializeUser((user, done) => { done(null, user) }) passport.deserializeUser((user, done) => { done(null, user) }) // ...login.html<html> <head lang="ja"> <meta charset="UTF-8"> <title>ログイン</title> </head> <body> <form action="/login" method="post"> <div> <label>ユーザID:</label> <input type="text" name="username"> </div> <div> <label>パスワード:</label> <input type="password" name="password"> </div> <div> <input type="submit" value="Login"> </div> </form> </body> </html>その他
ログインに成功したら
/login/ok
へリダイレクト、失敗したら/login/ng
へリダイレクトするような実装をします。
ただ、普通にやってしまうとログインに成功していないにも関わらず、http://localhost:3000/login/ok
と叩けばアクセスできてしまいます。。。
そこで便利なものがあります!
require('connect-ensure-login').ensureLoggedIn('/login')
を挟んでやれば、ログインしていない場合は指定した/login
にリダイレクトされるようにできます。app.js// ... app.get('/', (req, res) => { res.redirect('/login') }) app.get('/login', (req, res) => { res.sendFile('login.html', { root: path.join(__dirname, 'public') }) }) app.post('/login', passport.authenticate('local', { failureRedirect: '/login/ng', session: true }), (req, res) => { res.redirect('/login/ok') } ) app.get('/login/ng', (req, res) => { res.sendFile('ng.html', { root: path.join(__dirname, 'public') }) }) app.get('/login/ok', require('connect-ensure-login').ensureLoggedIn('/login'), // <--- こいつ!! (req, res) => { res.sendFile('ok.html', { root: path.join(__dirname, 'public') }) }); app.get('/logout', (req, res) => { req.logout() res.redirect('/login') }) // ...最後に
ログイン認証のセッション管理などを
req.isAuthenticated()
で制御させてみたんですけど、想定通りの動きはしなかった。。。これからは
connect-ensure-login
を使っていこーっと
一応、ソースコードを載せておきます。
- 投稿日:2020-03-22T03:24:58+09:00
最速Svelteを速攻デプロイするなら、Zeit NOW一択というメモ。
Svelteで何かデプロイしたい時には。
普段、バックエンドに引きこもっているデータエンジニアだが、たまにはフロントエンドに出ていってみようかと思い、最速JSに近しい存在という爆速(=>死語?)なSvelteいじって三日目。そろそろ(無料で)デプロイなるものをしてみたい今日このごろ。
...ということで、nodejs系を始めいろいろと無料でお気楽にデプロイできそうなZeit NOWを試してみた。
参考 Now でクラウドの複雑さから解放されよう、今すぐにgithub(かgitlabなど)の個人アカウントを持っているならば、たしかに、すぐさまデプロイできたのでメモを残しておく。Zeit now初体験だったが、10分ほどでデプロイをできた。
デプロイしたもの(カス):
アクセス先:
https://svelte1.now.sh・・・デプロイしたものは、Svelteの公式チュートリアルの一部を改悪しただけのカス。
SvelteをNOWにデプロイする手法(2020年版)
① NOW用Svelteをfolk
『zeit svelte』でググると出てくる以下から、
https://zeit.co/guides/deploying-svelte-with-zeit-now
自分が使っているgitリポジトリのアカウントを選ぶだけ。githubの場合
https://zeit.co/import/git?tab=github
あとは、SSOの認証を行うとディフォルトでprivateリポジトリにfolkしてくれる。
公開すると恥ずかしいサービスを作りたいとか、一山当てたいサービスを作りたい際には、privateリポジトリがディフォルトなのはありがたい限り。② NOW用Svelteをcloneして編集
folkたら当然、git cloneの類を持ってきて編集することになる。
フォルダ構成は以下の通り。ほぼSvelteのフォルダ構成通りだが.nowフォルダ配下がZeit NOWとの周りの調整を担ってくれているらしい。とりあえず、お試ししたい場合は、↑のApp.svelteを編集する。今回の場合。
<script> let count = 1 $: doubled = count * 2 $: tripled = count * 3 let handleClick = () =>{ count = tripled+3 } </script> <style> p { color: purple; font-family: 'Comic Sans MS', cursive; font-size: 2em; } </style> <main> <h1>滑る手おぢさん(仮)。</h1> <h2> <a href="https://zeit.co/docs" target="_blank" rel="noreferrer noopener"> ZEIT Now </a> でSvelteしてみる。突然だが、おい、オマイラ、掛け算という奴をしてみないか。すごく大きくなるぞ。 </h2> <br /> <p>元の数{count} しかして、け奴の×2は、 {doubled} 然らば、×3 {tripled}。けだし大きな数なり。</p> <button on:click={handleClick}> クリックしてみて 。 只今の元の数:{count} </button> </main>③ デプロイ
node/npm入っている人ならば、ひとまず、
npm i -g now
した後に、メール認証などを済ませた後は、
編集しているフォルダにて、
now --prod
するだけで、git add/git commit / git push、そしてNOWを介して本番デプロイという手順を一気に済ませられる。
セキュリティ云々を考えないなら、ほんとにお気軽。終わりに
少なくとも個人開発でのnodejsでの開発工程ならば、Zeit NOWは現時点では文句なしの存在ということを確認した。Svelteのバックエンドは数十分で始めた、Svelte+Firebaseのアプリ生活。で、firebaseが良さげと分かっている。
フロントエンド素人として悩ましいのが、node上でSvelteを動かす方法。絶賛開発中のSapperを試してはみたが、(英語でも)文書がなさすぎて素人にはつらすぎる(セキュリティ云々を気にするとfirebaseをバックエンドにしたアプリを公開できるは先になりそう、、)。どなたかSvelte/Sapperのベストプラクティスを紹介してくださらぬものかのぅ.(コーダー老人的堕ち)。とりあえず、Svelteお試しする分には楽しいので良しとするが。