TypeScript攻略
この本のサポートをお願いします: 購入する または 寄付する
(広告、ブロックしないでください。)

8 TypeScriptを使ったCommonJSベースのnpmパッケージの作成



この章では、パッケージマネージャnpm用のCommonJSモジュール形式に基づいたパッケージを作成するためにどのようにTypeScriptを使用するかについて説明します。

  GitHubリポジトリ: ts-demo-npm-cjs

この章では、リポジトリを探索します。ts-demo-npm-cjs GitHubからダウンロードできます。(意図的にパッケージとしてnpmに公開していません)

8.1 必要な知識

以下に精通している必要があります。

8.2 制約

この章では、TypeScriptが現在最もよくサポートしているものを使用しています。

特にNode.js上で、TypeScriptは現在ECMAScriptモジュールと.js以外のファイル名拡張子を実際にサポートしていません。

8.3 リポジトリのts-demo-npm-cjs

リポジトリの構成方法は次のとおりです。ts-demo-npm-cjs

ts-demo-npm-cjs/
  .gitignore
  .npmignore
  dist/   (created on demand)
  package.json
  ts/
    src/
      index.ts
    test/
      index_test.ts
  tsconfig.json

パッケージ用のpackage.jsonに加えて、リポジトリには次が含まれます。

package.jsonにはコンパイル用のスクリプトが含まれています。

ここに、2つのTypeScriptファイルのコンパイル結果が配置されます。

ts/src/index.ts       --> dist/src/index.js
ts/test/index_test.ts --> dist/test/index_test.js

8.4 .gitignore

このファイルには、git にコミットしたくないディレクトリが記載されています

node_modules/
dist/

説明

8.5 .npmignore

どのファイルを npm レジストリにアップロードして、どのファイルをアップロードしないかについては、git とは異なるニーズがあります。そのため、.gitignore の他に、ファイル .npmignore も必要です

ts/

2 つの相違点は、次のとおりです。

npm はデフォルトで node_modules/ ディレクトリを無視することに注意してください。

8.6 package.json

package.json は次のようになります

{
  ···
  "type": "commonjs",
  "main": "./dist/src/index.js",
  "types": "./dist/src/index.d.ts",
  "scripts": {
    "clean": "shx rm -rf dist/*",
    "build": "tsc",
    "watch": "tsc --watch",
    "test": "mocha --ui qunit",
    "testall": "mocha --ui qunit dist/test",
    "prepack": "npm run clean && npm run build"
  },
  "// devDependencies": {
    "@types/node": "Needed for unit test assertions (assert.equal() etc.)",
    "shx": "Needed for development-time package.json scripts"
  },
  "devDependencies": {
    "@types/lodash": "···",
    "@types/mocha": "···",
    "@types/node": "···",
    "mocha": "···",
    "shx": "···"
  },
  "dependencies": {
    "lodash": "···"
  }
}

プロパティを見てみましょう。

次の 2 つのサブセクションでは、残りのプロパティについて説明します。

8.6.1 スクリプト

プロパティ scripts は、npm run で呼び出せるさまざまなコマンドを定義します。たとえば、スクリプト cleannpm run clean で呼び出されます。前の package.json には、次のスクリプトが含まれています

IDE を使用している場合、IDE でアーティファクトを構築できるため、buildwatch のスクリプトは必要ありません。ただし、prepack のスクリプトには必要です。

8.6.2 dependenciesdevDependencies

dependencies に含める必要があるのは、パッケージをインポートするときに必要なパッケージのみです。それには、テストを実行するために使用されるパッケージなどは含まれません。

@types/ で始まる名前のパッケージは、タイプ定義を持たないパッケージに TypeScript タイプ定義を提供します。前者がないと後者を使用できません。これらは通常の依存関係ですか、それとも開発依存関係ですか。それは状況によって異なります

8.6.3 package.json に関する詳細情報

8.7 tsconfig.json

{
  "compilerOptions": {
    "rootDir": "ts",
    "outDir": "dist",
    "target": "es2019",
    "lib": [
      "es2019"
    ],
    "module": "commonjs",
    "esModuleInterop": true,
    "strict": true,
    "declaration": true,
    "sourceMap": true
  }
}

残りのオプションは tsconfig.json の公式ドキュメント で説明されています。

8.8 TypeScript コード

8.8.1 index.ts

このファイルはパッケージの実際的な動作を提供します

import endsWith from 'lodash/endsWith';

export function removeSuffix(str: string, suffix: string) {
  if (!endsWith(str, suffix)) {
    throw new Error(JSON.stringify(suffix)} + ' is not a suffix of ' +
      JSON.stringify(str));
  }
  return str.slice(0, -suffix.length);
}

ライブラリ Lodash の 関数 endsWith() を使用 しています。それゆえ Lodash は通常の依存関係です。ランタイムに必要です。

8.8.2 index_test.ts

このファイルには index.ts の単体テストが含まれています

import { strict as assert } from 'assert';
import { removeSuffix } from '../src/index';

test('removeSuffix()', () => {
  assert.equal(
    removeSuffix('myfile.txt', '.txt'),
    'myfile');
  assert.throws(() => removeSuffix('myfile.txt', 'abc'));
});

テストは以下の方法で実行できます

npm t dist/test/index_test.js

ご覧のとおり、TypeScript コードではなくテストのコンパイル済みバージョン (ディレクトリ dist/ 内) を実行しています。

単体テストフレームワーク Mocha についてさらに詳しい情報は、ホームページ を参照してください。