現役エンジニアがNode.jsを解説! 〜Node.jsのモジュール〜

公開日:2022-08-07
JavaScript
Node.js

https://www.youtube.com/watch?v=C8CGPHlHERg

この講座はYouTubeで動画形式でも用意しています。合わせてご覧ください。

目的

Node.jsのモジュールを理解する。

モジュールとは

ソフトウェア工学におけるモジュールは、ソフトウェアシステムを構成する部分的プログラムです。この抽象的な説明だと理解が難しいので、実際にモジュールを扱いながら説明をしていきます。

標準モジュールを使用する

Node.jsには基本的な操作のできる標準モジュールが提供されていて、Node.jsをインストールすると利用できます。

例1)Webサーバーを構築したい場合

「http」モジュールを使用します。

https://nodejs.org/dist/latest-v16.x/docs/api/http.htmlhttps://nodejs.org/dist/latest-v16.x/docs/api/http.html

1行目で読み込まれているhttpがモジュール名になります。
実際のWeb開発では、より高度な機能が使えるExpressなどのWebフレームワークを使われることが多いですが、httpモジュールがそのベースになっています。

httpモジュールでWebサーバーを実行するプログラム
// httpがモジュール名
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;

// createServerのメソッドに処理の内容を書いていく
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello World");
});

// サーバーが起動したら、listenされたら実行される処理を記述
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

例2)ファイルを操作したい場合

「fs」モジュールを使用します。fsとはファイルシステムの略称です。

https://nodejs.org/dist/latest-v16.x/docs/api/fs.htmlhttps://nodejs.org/dist/latest-v16.x/docs/api/fs.html

fsモジュールのreadFileというメソッドで下記にあるdata1.txtのテキストファイルを読んでいます。

テキストファイルを読み込むプログラム
const fs = require("fs");
fs.readFile("data1.txt", "utf-8", (err, data) => {
   if (err) throw err;
   console.log(data);
});

同期・非同期のモジュール

fsに限らず同期・非同期のモジュールがそれぞれ用意されていることが多いです。
Node.jsは基本的に非同期で処理が実行されていくプログラミング言語になっていますが、readFileの同期版であるreadFileSyncを使用し同期処理としての実装も可能です。

同期処理としてファイル読み込みを行うプログラム
const fs = require("fs");
try {
  // 同期
  const buff = fs.readFileSync("data1.txt", "utf8");
  console.log(buff);
} catch (e) {
  console.log(e.message);
}

同期・非同期のどちらを使うのかですが、基本的にはパフォーマンスを考慮すると非同期のモジュールを使用すべきです。しかし、パフォーマンスの考慮が不要な場合は同期のモジュールを使用したほうが実装しやすいです。

また最近のNode.jsのバージョンではPromiseに対応したモジュールも提供されています。Promise版のreadFileを使った場合はasync/awaitで記載しています。

Promise対応したreadFileを使うプログラム
// 非同期(Promise)
const fs = require("fs").promises;
const readFile = async (file) => {
  try {
    const buff = await fs.readFile(file, "utf-8");
    console.log(buff);
  } catch (e) {
    console.log(e.message);
  }
};
readFile("data1.txt");

Promiseに対応しているメソッドが使えるのであれば一番おすすめの書き方です。非同期処理やPromiseについては、動画で解説していますので参考にしてみてください。

モジュールを自作する

Node.jsのモジュール化の仕組みをCommonJS modulesと言います。CommonJS modulesのルールに従った書き方でモジュールを記載することで自作のモジュールも扱うことができます。

https://nodejs.org/docs/latest/api/modules.html#modules-commonjs-moduleshttps://nodejs.org/docs/latest/api/modules.html#modules-commonjs-modules

モジュールのエクスポートはmodule.exportsexports、モジュールのインポートはrequireを使って、コード内で自作モジュールを使用できます。

モジュールのエクスポート

hello_world.js
const sayHelloWorld = () => {
  console.log("hello world!");
};
exports.sayHelloWorld1 = sayHelloWorld1;

exports.モジュール名=モジュールの内容でモジュール化できました。

これを呼ぶ場合、{} の中に呼び出すモジュール、requireの後ろにファイル指定します。

index.js
const { sayHelloWorld1 } = require("./hello_world");
sayHelloWorld();

module.exportsを使用した場合

以下ではpersonというオブジェクトをexportしています。

file.js
const person = {
  firstName: "Ken",
  lastName: "Takahashi",
  age: 29,
  gender: "male",
  interests: [
    {
      name: "programming",
      emoji: "💻",
    },
    {
      name: "motorcycle",
      emoji: "🏍",
    },
  ],
  greeting: function () {
    console.log("Hi! I'm " + this.firstName + " " + this.lastName);
  },
};

module.exports = person;

これを呼ぶ場合には次の書き方になります。

index.js
const person = require("./person");
person.greeting();

先程までとの違いとして {} が不要になります。また、module.exportsを使った方法は1つしかexportできません。

(補足)JavaScriptにおけるモジュール

フロントエンドJavaScriptのモジュールの扱い方は少し異なり、フロントエンドの場合は、importexport文を使用してモジュールを扱います。そのため、場合によって使い分けが必要です。詳しくはコチラの記事も参考にしてみて下さい。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Moduleshttps://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Modules

まとめ

今回はNode.jsのモジュールについて学習しました。次回はNode.jsのパッケージ管理について学んでいきます。