[note] node.js
node.jsとは
Node.js is an asynchronous, event-driven JavaScript environment designed for building scalable network applications.
Node.jsは、スケーラブルなネットワークアプリケーションを構築するために設計された非同期、イベントドリブンなJavaScript環境です。
Node.jsをバックエンドに使うべきユースケース
環境構築
環境構築(docker)
nodeを実行するには
REPL
ユーザーとインタプリタが対話的にコード片を実行できるもの
! ~/W/d/dandyyy *… node 2022-02-16 14:05:12
Welcome to Node.js v14.0.0.
Type ".help" for more information.
> console.log("test")
test
undefined
>
jsファイル(ここではvscode)
pwd
/Users/tanokentaro/Workspace/develop/dandyyy
// vscodeのbackend/index.jsを起動
code backend/index.js
backend/index.js ~編集~
console.log("test");
// backend/index.jsを実行
! ~/W/d/dandyyy *… node backend/index.js 2022-02-16 14:18:57
test
vscode 拡張機能
- npm intellisense
- eslint
- prettier
- document this
- rest client
新規プロジェクトを作成
プロジェクトの初期化
質問にはよしなに答える
完了すればpackage,json(メタ情報、依存関係、ソースコードの場所などのnodepjの中で最も重要なファイル)が作られる
npm init
package.json
{
// メタ情報
"name": "dandyyy",
"version": "1.0.0",
"description": "",
"main": "index.js",
// スクリプト
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node backend/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
// pjに使用するライブラリを記述する追加のプロパティ
"dependencies": {
"express": "^4.17.2"
}
}
NPM スクリプトで開発タスクを自動化
実行、テスト、ビルドなど
package.jsに関連づけられたターミナルコマンドを定義することで自動化
基本タスク
- start 実行
- test
- build
- lint
開発者間で一貫したスクリプト名にする
例
"scripts": {
"start": "node index.js",
"build": "tsc",
"lint": "eslint",
"test": "jest"
}
スクリプトを実行するには
terminal上で
startの場合はnpm startだけでOK
npm run {スクリプト名}
Node.js プロジェクトで依存パッケージを追加する
たいていの場合はライブラリやツールなど外部のコードに依存する = 依存関係と呼ばれる
npm install express
node_modulesファイルがプロジェクト上に追加される
{
"name": "dandyyy",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node backend/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.2" // 追加
}
}
commitしないものを.gitignoreで管理
理由
- 膨大な量
- npm installだけで依存パッケージがインストールされるのでわざわざcommit必要ない
touch .gitignore
.gitignore
node_modules
npmはcli及びパッケージインストーラーとして機能する
開発環境だけで使う
npm install --save-dev jest
"devDependencies": {
"jest": "^4.17.2"
}
パッケージのアンインストール
npm uninstall jest
package-lock.json
依存関係を更新すると作成される
npmによって依存関係が更新されるたびに更新される
全ての依存関係を推移する役割を果たすため、リポジトリにコミットする
npm ciコマンドがこれがないと実行できない
パッケージが頻繁に更新されても余計な更新をしないように自動的にロックしてくれる = パッケージの更新は自分らでしないといけない
パッケージの更新
更新が必要なパッケージの表示
赤で表示される部分は全て最新にできる
今はない
npm outdated
更新
npm update
パッケージバージョンは3つの数字で作られる
セマンティックバージョニング
- 更新範囲を示す特殊文字
- ^(キャレット):デフォルト、マイナーとパッチのみ更新
- ~:パッチ更新のみ、コンパイラやリンターなどユーザー側で変更が必要
- なし(バージョン番号のみ):更新なし
- *:常に最新に更新する
- 4:メジャーバージョン(コードの互換性に影響を与える可能性)
- 17:マイナーバージョン(機能追加)
- 2:パッチバージョン(コードない動作の修正、安全)
"express": "^4.17.2"
脆弱性を npm audit でチェック
今はなし
解決方法などの情報を取得できる
~/W/d/dandyyy *… npm audit
=== npm audit security report ===
found 0 vulnerabilities
in 50 scanned packages
Express で Web API を構築
ヘルパーをインストール
- bosy-parser
- cors
- nodemon
npm install bosy-parser cors
npm install --save-dev nodemon
{
"name": "dandyyy",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node backend/index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.2",
"cors": "^2.8.5",
"express": "^4.17.2"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
api作成
Build the server
server.js
// expressを読み込む
const express = require("express");
// ポート番号を読み込む(環境変数から読み取る or デフォルトとして5000を設定)
const port = process.env.port || process.env.PORT || 5000;
// expressオブジェクトのインスタンスを作成(初期化)
const app = express();
// イベントハンドラを設定(port番号をここでリッスンさせる)
// サーバが起動した時に
app.listen(port, () => {
console.log("server api!!");
});
Setting up cors and bodyparser
// expressを読み込む
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
// ポート番号を読み込む(環境変数から読み取る or デフォルトとして5000を設定)
const port = process.env.port || process.env.PORT || 5000;
// expressオブジェクトのインスタンスを作成(初期化)
const app = express();
// configure app
// ユーザーがサーバーに送信した情報を読み取る
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors({ origin: /http: \/\/localhost/ }));
app.options("*", cors());
// イベントハンドラを設定(port番号をここでリッスンさせる)
// サーバが起動した時に
app.listen(port, () => {
console.log("server api!!");
});
package.jsonのメタデータを出力するテスト用api作成
// expressを読み込む
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
// テストとしてpackage.jsonからのデータを表示させる
const package = require("../package.json");
// ポート番号を読み込む(環境変数から読み取る or デフォルトとして5000を設定)
const port = process.env.port || process.env.PORT || 5000;
// api routerを設定
const apiRoot = "/api";
// expressオブジェクトのインスタンスを作成(初期化)
const app = express();
// configure app
// ユーザーがサーバーに送信した情報を読み取る
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// apiとクライアントアプリのホスティング環境が別々の場所にあっても読み出し可能にする
app.use(cors({ origin: /http: \/\/localhost/ }));
app.options("*", cors());
// configure routes
const router = express.Router();
router.get("/", (req, res) => {
// テストとしてpackage.jsonからのデータを表示させる
res.send(`${package.description} - v${package.version}`);
});
// register all our routes
app.use(apiRoot, router);
// イベントハンドラを設定(port番号をここでリッスンさせる)
// サーバが起動した時に
app.listen(port, () => {
console.log("server api!!");
});
各調査
require
process.env.port
process.env.PORT
app.use
bodyParser.urlencoded
/http: //localhost/
app.listen構文
フォルダ構成
dbとの連携
crud api
ejs テンプレエンジンExpress使うのでざつと
<%= obj.id %>
こんな感じで値を出力できる
フロントとの連携
デプロイ
Expressの基本おさらい
Expressの基本手順
- expressオブジェクトの用意
- appオブジェクトの作成(実体化)
- ルーティングの設定
- 待ち受け
app.jsとroutes配下ファイルの役割
routes配下に***.jsファイル作成
そこにrouterオブジェクトを使った処理を用意
例
const express = require("express");
const router = express.Router();
router.get("/", (req, res, next) => {
var msg = "※何か書いて送信して下さい。";
if (req.session.message != undefined) {
msg = "Last Message: " + req.session.message;
}
var data = {
title: "Hello!",
content: msg,
};
res.render("hello", data);
});
router.post("/post", (req, res, next) => {
var msg = req.body["message"];
req.session.message = msg;
var data = {
title: "Hello!",
content: "Last Message: " + req.session.message,
};
res.render("hello", data);
});
module.exports = router;
appjsで***.jsをロードし、/***(url)に割り当てる
var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
var hello = require("./routes/hello");//ここ
const session = require("express-session");
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
var app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
var session_opt = {
secret: "keyboard cat",
resave: false,
saveUninitialized: false,
cookie: { maxAge: 60 * 60 * 1000 },
};
app.use(session(session_opt));
app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/hello", hello);//ここ
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;
Discussion