Chuyển đến nội dung chính

レッスン 3: モジュール システムとパッケージ管理

CommonJS と ES モジュール、モジュール解決アルゴリズム。 Package.json フィールドのエクスポート、条件付きエクスポート。 npm、pnpm ワークスペース。 Node.js 組み込みテスト ランナー、権限モデル。

💻 プログラミング — レッスン 3 レッスン 3: モジュール システムとパッケージ管理

Node.js コア: 基本から高度まで

パート 1: Node.js の内部構造

xdev.asia

1. CommonJS 対 ES モジュール

特長共通JS (CJS)ESモジュール(ESM)
構文require() / module.exportsインポート/エクスポート
読み込み中同期非同期
トップレベルの待機いいえはい
__ディレクトリ名はいimport.meta.dirname (ノード 21 以降)
JSONインポートrequire('./data.json'){ type: 'json' } を使用して './data.json' からデータをインポートします
木を揺らすいいえはい (静的解析)
// ESM — recommended
import { readFile } from 'node:fs/promises'
import path from 'node:path'

// Dynamic import
const module = await import('./utils.js')

// import.meta
console.log(import.meta.url)      // file:///path/to/file.js
console.log(import.meta.dirname)  // /path/to (Node.js 21+)
console.log(import.meta.filename) // /path/to/file.js

2. Package.json エクスポート フィールド

{
  "name": "my-lib",
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    },
    "./utils": {
      "import": "./dist/utils.mjs",
      "require": "./dist/utils.cjs"
    }
  },
  "files": ["dist"],
  "engines": {
    "node": ">=22"
  }
}

3.pnpmワークスペース

# pnpm-workspace.yaml
packages:
  - 'packages/*'
  - 'apps/*'
# Thêm dependency cho workspace
pnpm add lodash --filter @myorg/server
pnpm add @myorg/shared --filter @myorg/server --workspace

# Chạy script cho tất cả packages
pnpm -r run build
pnpm -r --parallel run dev

4. 権限モデル (Node.js 22+)

# Chạy với permission giới hạn
node --experimental-permission \
  --allow-fs-read=/app/data \
  --allow-fs-write=/app/logs \
  --allow-child-process \
  app.js

# Kiểm tra permission trong code
if (process.permission.has('fs.read', '/etc/passwd')) {
  console.log('Has read permission')
}

5. 内蔵テストランナー

import { describe, it, before, after, mock } from 'node:test'
import assert from 'node:assert/strict'

describe('Calculator', () => {
  it('adds two numbers', () => {
    assert.strictEqual(1 + 2, 3)
  })

  it('handles async', async () => {
    const result = await Promise.resolve(42)
    assert.strictEqual(result, 42)
  })

  it('supports mocking', () => {
    const fn = mock.fn((a: number, b: number) => a + b)
    fn(1, 2)
    assert.strictEqual(fn.mock.calls.length, 1)
    assert.deepStrictEqual(fn.mock.calls[0].arguments, [1, 2])
  })
})
node --test --test-reporter spec

次の記事: TypeScript と最新の JavaScript — tsx、ts-node、タイプストリッピング。