ノード.js開発のジャンプスタート

87,000以上の星と3,100人の貢献者を擁し、 ノード.js 2022年にエンタープライズ開発者にとって主要な選択肢になりました。 それは オープンソース、開発者がJavaScriptでさまざまなサーバー側のツールやアプリケーションを構築するのに役立つクロスプラットフォームのランタイム環境。 

開発者は Node.js を使用して、堅牢性の高いアプリのおかげで、高速でスケーラブルなリアルタイム アプリを構築できます イベント駆動型ランタイム。 また、 非同期。 Node.jsは、トラフィックの急増に応じて、高スループットで膨大な数の同時接続を処理できます。 したがって、マイクロサービス アーキテクチャの構築に最適です。 

イベント・キュー・グラフィック

 

ユーザーは私たちをダウンロードしました ノード.js ドッカー公式イメージ Docker Hub から 10 億回以上。 この大幅なダウンロード率を推進しているのは何ですか? 合理化のためにDockerコンテナに対する需要はますます高まっています 開発ワークフローを提供しながら、Node.js開発者は、プロジェクトに合わせたツール、アプリケーションスタック、およびデプロイメント環境を選択して革新する自由を提供します。 

Node.jsアプリを迅速かつ簡単にコンテナ化し、一般的なNodeの互換性の問題をシームレスに回避しながらデプロイを加速する方法を説明します。 これにより、アプリケーションはさまざまな CPU アーキテクチャでクロスプラットフォームを簡単に実行できます。 

アプリケーションのビルド       

ノードjsエクスプレス

 

このチュートリアルでは、Docker を使用して Node .js To Do リスト アプリを簡単に構築する方法について説明します。 

まず、Docker を使用せずに.js Node で簡単な To-Do リスト アプリケーションを作成します。 アプリケーションで Redis バックエンド データベースを使用してタスク リストを作成および削除する方法について説明します。 

次に、そのアプリケーションの Docker イメージをビルドします。 また、Docker Compose を使用して、コンテナー内にアプリケーションを迅速にデプロイする方法についても説明します。 始めましょう。 

前提 条件

  • ティッカー –ノード.jsアプリの開発に使用されるノードパッケージマネージャー 
  • ノード.js –Webアプリケーションを構築するためのランタイム
  • 述べる – Node用のバックエンドWebアプリケーションフレームワーク.js 
  • ブートストラップ –レスポンシブなフロントエンドWeb開発のためのツールキット
  • レディス –キャッシュ、データストレージ、およびメッセージブローカーに使用されるメモリ内、キー値、NoSQLデータベース
  • ドッカーデスクトップ個々のコンテナを作成、共有、実行するためのソフトウェア開発ツールスイート

始める

インストールしたら、 マシン上のノード.jsパッケージで、次の手順に従って、簡単な To Do リスト アプリを最初から作成します。

NodeJS から始める

  1.  空のディレクトリを作成します。

mkdir todolist

      2. を実行します。 npm init  コマンドを使用して、新しい npm パッケージを設定します。

npm init

このユーティリティは、 package.json アプリとその依存関係を記述するファイル。

 
{
  "name": "todolist",
  "version": "1.0.0",
  "description": "A Sample Todo-List app",
  "main": "todolist.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ajeetraina/todolist.git"
  },
  "keywords": [
    "node.js"
  ],
  "author": "Ajeet Singh Raina",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/ajeetraina/todolist/issues"
  },
  "homepage": "https://github.com/ajeetraina/todolist#readme"
}

新しいパッケージ.jsonを使用すると、 走る npm インストール.

npm install --save express redis ejs dotenv

これがあなたの結果です:

+ [email protected]
+ [email protected]
+ [email protected]
+ [email protected]
added 79 packages from 106 contributors and audited 79 packages in 5.112s

4 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

次に、 package.json ファイルを使用して、次のエントリを表示します。

{
  "name": "todolist",
  "version": "1.0.0",
  "description": "A Sample Todo-List app",
  "main": "todolist.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ajeetraina/todolist.git"
  },
  "keywords": [
    "node.js"
  ],
  "author": "Ajeet Singh Raina",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/ajeetraina/todolist/issues"
  },
  "homepage": "https://github.com/ajeetraina/todolist#readme",
  "dependencies": {
    "dotenv": "^16.0.0",
    "ejs": "^3.1.6",
    "express": "^4.17.3",
    "redis": "^4.0.6"
  }
}

ノデモンのインストール

ノデーモン は、運用環境ではなく、主に開発目的で使用される便利な CLI ユーティリティです。 ソースコードの変更を監視し、アプリサーバーを自動的に再起動して適用します。 さらに、スクリプトを使用して実行する場合は、開発依存関係にnodemonを追加できます。 または、グローバルにインストールすることもできます。 ノデーモンはオープンソースであり、 GitHub で入手できます。

nodemonをインストールするための推奨される方法は、 エヌピーエム 効用。

npm install --save-dev nodemon

これがあなたの結果です:

+ [email protected]
added 106 packages from 55 contributors and audited 185 packages in 3.514s

18 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

これで、nodemonが パッケージ.jsonに追加されているのを確認できるはずです ファイル:

{
  "name": "todo-list",
  "version": "1.0.0",
  "description": "A Sample Todo List app",
  "main": "app.js",
  "scripts": {
    "start": "nodemon app.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ajeetraina/todolist.git"
  },
  "keywords": [
    "nodejs",
    "express"
  ],
  "author": "Ajeet S Raina",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/ajeetraina/todolist/issues"
  },
  "homepage": "https://github.com/ajeetraina/todolist#readme",
  "dependencies": {
    "dotenv": "^16.0.0",
    "ejs": "^3.1.6",
    "express": "^4.17.3",
    "redis": "^4.0.6"
  },
  "devDependencies": {
    "nodemon": "^2.0.15"
  }
}

To Do リスト Web アプリの定義

まず、空の app.js Express.js フレームワークを使用して Web アプリを定義するファイル。 次に、ビルド プロセスを開始する前に、すべての重要なコンポーネントが配置されていることを確認する必要があります。 

JavaScript コードの最初の部分では、すべての重要なパッケージをプロジェクトにインポートします。 ただし、Express アプリケーションのインスタンスを redis、本文パーサー、およびパスと共に作成する必要もあります。 次に、express 変数を初期化する必要があります。 述べる は、Webおよびモバイルアプリケーション向けの堅牢な機能を備えた、最小限でありながら柔軟なNode.js Webアプリケーションフレームワークです。 Expressには、と呼ばれるミドルウェアモジュールが必要です。 body-parser から受信データを抽出するには 投稿 依頼。

‘use strict’;

const express = require('express');
const redis = require('redis');
const path = require('path');
const port = 3000;
const bodyParser = require('body-parser');


var app = express();

const client = redis.createClient();

client.on('connect', () => {
  console.log('Successfully connected to Redis...');
});

ビュー エンジンの定義

次に、ビューエンジンが必要です。 は、Web ページのレンダリングに役立ちます。 また、Embedded JavaScript (EJS) と呼ばれる一般的なビュー エンジンも使用します。 これは基本的に、開発者がプレーンなJavaScriptを使用してHTMLを生成できるようにする単純なテンプレート言語エンジンです。 コード セクションでは、ビュー エンジンへのパスを定義します。 bodyParser は、各要素の正規化に役立ちます。

このコードスニペットの最後の行では、 /公共 ディレクトリ — そのため インデックス.EJS それをつかんでフロントエンドに表示することができます:

app.set('views'), path.join(__dirname, 'views');
app.set('view engine', 'ejs');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));

app.use(express.static(path.join(__dirname, 'public')))

取得

このコードスニペットでは、 エクスプレスルーター を使用して、アプリのルーティングを処理します。 ユーザーが Web ブラウザーからアプリを要求するたびに、Redis データベースからの応答が配信されます。

app.get('/', (req, res) => {
  var title = 'A Simple Todo-List App';
  var counter = 0;
  client.LRANGE('todo', 0, -1, (err, reply) => {
    if(err){
      res.send(err);
      return;
    }
    res.render('index', {
      title: title,
      todo: reply,
      counter: counter
    });
  });
});

クイックヒント: Redis リストは、挿入順に格納されている文字列のリストとして定義できます。

  • ティッカー: リストの右側に新しい要素を追加します。 すなわち リストの末尾に要素を挿入します)
  • LRANGE: 指定された "start" オフセットと "stop" オフセットに基づいてリスト要素のサブセットを取得します

投稿

同様に、Redisデータベースにデータをプッシュする場合は常に、Redisを使用します RPUSH 次に示すようにコマンド:

app.post('/todo/add', (req, res, next) => {
  var todo = req.body.todos;
  client.RPUSH('todo', todo, (err, reply) => {
    if(err){
      res.send(err);
      return;
    }
    res.redirect('/');
  });
});

Redisデータベース内のメッセージをインデックスで削除する場合は、次のコマンド LREM を使用します。 この Redis コマンドは、要素と等しい要素の最初のカウントの出現箇所をリストから削除します。

app.post('/todo/delete', (req, res, next) => {
  var delTODO = req.body.todo;
  var deleted = '__DELETED__';
  client.LRANGE('todo', 0, -1, (err, todo) => {
    for(let i = 0; i < delTODO.length; i++){
      client.LSET('todo', delTODO[i], deleted);
    }
    client.LREM('todo', 0, deleted);
    res.redirect('/');
  });
});

一方、次のエントリは、サーバーを起動し、ポート 3000 で接続をリッスンするようにアプリに指示します。

app.listen(3000, () => {
  console.log('Server listening at port 3000...');
});

module.exports = app;

完成したコードは次のようになります。

‘use strict’;

const express = require('express');
const redis = require('redis');
const path = require('path');
const port 3000
const bodyParser = require('body-parser');


var app = express();

const client = redis.createClient();

client.on('connect', () => {
  console.log('Successfully connected to Redis...');
});

app.set('views'), path.join(__dirname, 'views');
app.set('view engine', 'ejs');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => {
  var title = 'A Simple Todo App List';
  var counter = 0;
  client.LRANGE('todo', 0, -1, (err, reply) => {
    if(err){
      res.send(err);
      return;
    }
    res.render('index', {
      title: title,
      todo: reply,
      counter: counter
    });
  });
});

app.post('/todo/add', (req, res, next) => {
  var todo = req.body.todos;
  client.RPUSH('todo', todo, (err, reply) => {
    if(err){
      res.send(err);
      return;
    }
    res.redirect('/');
  });
});

app.post('/todo/delete', (req, res, next) => {
  var delTODO = req.body.todo;
  var deleted = '__DELETED__';
  client.LRANGE('todo', 0, -1, (err, todo) => {
    for(let i = 0; i < delTODO.length; i++){
      client.LSET('todo', delTODO[i], deleted);
    }
    client.LREM('todo', 0, deleted);
    res.redirect('/');
  });
});

app.listen(3000, () => {
  console.log('Server listening at port 3000...');
});

module.exports = app;

ビュー エンジンの構築

ビュー エンジンを構築するプロセスは比較的簡単です。 これを行うには、「views」という名前の空のフォルダーを作成し、次の名前のファイルにコンテンツを追加します。index.ejs:

!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://bootswatch.com/4/slate/bootstrap.min.css">
  <title>A Simple Todo List App</title>
</head>
<body>
  <div class="container">
    <h1 class="text-center"> <%= title %> </h1>
    <img src="/images/todo.jpeg" class="center"  width="300" alt="">
    <form action="/todo/add" method="POST">
      <div class="form-group">
        <input type="text" class="form-control" name="todos" placeholder="Start typing and Press Enter...">
      </div>
    </form>
    <form action="/todo/delete" method="POST">
    
      <% todo.forEach( (list) => { %>
        <div class="alert alert-success">
          <input type="checkbox" class="form-check-input mt-2" name="todo" value="<%= counter %>">
          <h4 class="d-inline">> </h4> <strong><%= list %></strong>
        </div>
        <% counter++ %>
      <% }) %>
        <input type="submit" value="Remove" class="btn btn-primary">
    </form>
    
  </div>
</body>
</html>

次に、システムでRedisサーバーを実行してみましょう。 Mac OSを使用している場合は、以下に示すように自作を使用することをお勧めします。

BREW インストール REDISです

BREWサービス開始

これが完了したら、次の方法で redis-cliRedisサーバーに接続できることを確認します。

redis-cli
127.0.0.1:6379> info
..

最後に、次のコマンドでnodemonを起動するだけです。 結果はすぐに表示されます。

ノデモン 。

[nodemon] 2.0.12
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node .`
Server listening at port 3000...
Successfully connected to Redis...

次に、アプリが正しく動作していることを確認します。 ブラウザを開き、アドレスバーの http://localhost:3000 にアクセスします。 表示される内容は次のとおりです。

簡単にできるリストアプリ

 

やることリストを入力し始めると、Redisデータベースに次のアクティビティが表示されます。

1650438955.239370 [0 172.17.0.1:59706] "info"
1650438999.498418 [0 172.17.0.1:59708] "info"
1650439059.072301 [0 172.17.0.1:59708] "lrange" "todo" "0" "-1"
1650439086.492042 [0 172.17.0.1:59708] "rpush" "todo" "Watch netflix"
1650439086.500834 [0 172.17.0.1:59708] "lrange" "todo" "0" "-1"
1650439094.054506 [0 172.17.0.1:59708] "rpush" "todo" "Attend Meeting"
1650439094.059366 [0 172.17.0.1:59708] "lrange" "todo" "0" "-1"
1650439099.726832 [0 172.17.0.1:59708] "rpush" "todo" "Walk for 30 min"
1650439099.731735 [0 172.17.0.1:59708] "lrange" "todo" "0" "-1"

Docker デスクトップを使用したマルチコンテナノード.jsアプリの構築

公式のDockerイメージを使用して、Dockerコンテナ内でこのアプリを実行する方法を評価しましょう。 まず、次のことを行う必要があります ドッカーデスクトップをインストールする — これにより、アプリの Docker イメージを構築できます。

ドッカーの使用を開始する

次に、"Dockerfile" という名前の空のファイルを作成します。

タッチドッカーファイル

お気に入りのテキストエディタを使用して、 Dockerfile.次に、基本イメージを定義する必要があります。 

したがって、Node.jsの長期サポート(LTS)バージョンと最小限のものを使用していることを確認してください alpine 画像の種類。 これにより、イメージのフットプリント、ひいては攻撃対象領域を最小限に抑えることができます。

ノードから:LTS-アルパイン

クイックヒント: 明示的で決定論的な Docker イメージ ベース タグを使用することをお勧めします。 Docker イメージが小さいほど、再構築が迅速になります。 Docker イメージのビルドも非常に多様です。 たとえば、 ノード:最新[のーど:ちゅん タグにタグを付けると、すべてのビルドで新しくビルドされた Docker ノード イメージがプルされる可能性があります。 これにより、非決定論的な動作が発生し、デプロイの一貫性が妨げられる可能性があります。 

Node.jsとDockerがどのように連携できるかについてもっと知りたいですか? ドッカーコン2022にご参加ください — 学習する場所 ノード.jsおよび JavaScript プロジェクトを管理するためのベスト プラクティス コンテナの開発、テスト、運用中。

次に、イメージのアプリケーション コードを格納するディレクトリをすばやく作成しましょう。 これは、アプリケーションの作業ディレクトリとして機能します。

WORKDIR '/var/www/app'

Node.js と NPM の両方がイメージ内にプリインストールされています。 ただし、アプリの依存関係をインストールするには、 エヌピーエム バイナリ。 

アプリのソース コードを Docker イメージ内にバンドルするには、 写し 命令:

写し。。

アプリはポート 3000 にバインドされます。 [ 晒す 持っているための指示 ドッカーデーモン 適切にマッピングします。

エクスポージャー3000

あなたのシンプル ドッカーファイル 次のようになります。

FROM node:lts-alpine

COPY package*.json ./
  
WORKDIR '/var/www/app'

RUN npm install --save express redis ejs dotenv 

COPY . .

EXPOSE 3000

そうは言っても、Dockerイメージをビルドする必要があります。 次のコマンドを入力してこのプロセスを開始すると、すぐに出力が生成されます。

docker build -t ajeetraina/todolist .

docker images
REPOSITORY                             TAG       IMAGE ID       CREATED         SIZE
ajeetraina/todolist                    latest    6aeeaac8ace3   2 minutes ago   131MB

次に、 .ドッカー無視 ファイル。 このファイルはよく似ています.gitignore. これにより、Docker デーモンが Docker ビルド の実行中に受け取る初期ビルドコンテキストにファイルが追加されるのを防ぎます。

これを作成します ..ドッカー無視 ファイルと同じディレクトリに ドッカーファイル を次のように置き換えます。

node_modules
.git

これにより、ローカル モジュールとデバッグ ログが Docker イメージにコピーされなくなります。 これが発生すると、イメージ内にインストールされているモジュールが上書きされる可能性があります。

Docker イメージを再構築して検証すると、約 4 MB のディスク領域を節約できます。

docker images                        
REPOSITORY                             TAG       IMAGE ID       CREATED          SIZE
ajeetraina/todolist                    latest    453c5aeae5e0   3 seconds ago    127MB

最後に、Docker 作成ファイルを作成します。 この 1 つの YAML ファイルを使用すると、フロントエンド アプリと Redis データベースを指定できます。

services:
  
  app:
    build: ./
    volumes:
       - ./:/var/www/app
    ports:
      - 3000:3000
    environment:
      - REDIS_URL=redis://db:6379
      - NODE_ENV=development
      - PORT=3000
    command:
       sh -c 'node app.js'
    depends_on:
      - db
 
  db:
    image: redis

サンプル アプリケーションには、次の部分があります。

  • Docker イメージによってサポートされる 2 つのサービス (フロントエンド Web アプリとバックエンド データベース)
  • フロントエンド、ポート3000経由でアクセス可能
  • depends_on パラメーターを使用して、フロントエンド サービスの開始前にバックエンド サービスを作成できます
  • フロントエンドに接続された 1 つの永続ボリューム

次に、 REDIS_URL あなたの中で app.js ファイル — Docker 作成ファイル内で Redis エンドポイントを渡すことができます。

const client = redis.createClient({ url: process.env.REDIS_URL });

 

次に、を使用してサービスを開始する必要があります ドッカー-作成 命令。 これで、Node.jsやることリストアプリを作成してデプロイしました。 これは、以前と同様にブラウザで使用できます。

リストアプリを簡単に実行

 

もう少し深く掘り下げたいですか? 私の完全なプロジェクトコードはで利用可能です 私の GitHub ページ.

結論

Docker は、最新のアプリケーションの構築、実行、共有のプロセスを加速するのに役立ちます。 Docker公式イメージは、慣れ親しんだ技術スタックに関係なく、独自のアプリケーションを開発するのに役立ちます。 1 つの YAML ファイルで、Docker Compose を使用して Redis を使用してマルチコンテナー ノード.js アプリを簡単に構築する方法を示しました。

Docker Composeを使用して、実際のマイクロサービスアプリケーションを開発することもできます。 いくつかの追加手順を実行するだけで、このチュートリアルを適用しながら、はるかに複雑なアプリケーションを構築できます。 ハッピーコーディング! 

関連資料

 

フィードバック

「ノード.js開発をジャンプスタートする」に関する0の考え