はじめに
はじめまして、AnyManagerのエンジニアの鳥居と申します。
新卒でAnyMindに入社してから、AnyManagerの開発に携わっております。
今回は開発をする中で、Typescriptでnpm packageの作成をする事がありましたので、その方法を紹介したいと思います。
環境
弊社では以下の環境、ツールを使って開発を行っております
- MacOS Catalina 10.15.7
- Bitbucket:リポジトリ管理ツール。作成したモジュールのリポジトリを管理しています。
- Typescript 4.6.3
実現したい事
以下のようなことをゴールとします。
- typescriptで作成したモジュールをjavascriptにコンパイルし、異なるリポジトリ内ででモジュールを呼び出し可能にする。

以下のようなリポジトリ構成で話を進めます。
- Main Repository: 処理のエントリーポイント。Module 1とModule 2を内部でimport。
- Module 1: Main Repositoryで使用されるmodule。Module 3を内部でimport。
- Module 2: Main Repositoryで使用されるmodule。Module 3を内部でimport。
- Module 3: Module 1とModule 2で共通してimportされるmodule。
ゴールを達成するためには、tsconfig.jsonとpackage.jsonを正しく設定しなければなりません。
tsconfig.jsonの設定(Module1、Module2、Module3側)
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true
},
"include": ["src/**/*"]
}
declaration: コンパイル時に.d.tsファイルを作成する必要があるのでtrueにします。target: どのjavascriptのバージョンにトランスパイルするかを指定します。今回はコンパイルされたjavascriptがブラウザで動作するかつ、古いブラウザでも動作するようにes5を指定しています。 Typescript公式ドキュメントoutDir: javascriptをどのディレクトリ配下に配置するかを指定します。
declarationMapをtrueにすると、エディターなどで定義元のファイルに飛ぶ際に、.d.tsファイルではなく、.tsファイルに飛べるようになります。
ただし、今回はコンパイルのアウトプットに*.tsファイルを含めないので省略しています。
packages.jsonの設定(Module1、Module2、Module3側)
nameをモジュール名に応じて適宜変更してください
package.json
{
"name": "@anymind/module3",
"version": "1.0.0",
"private": true,
"files": ["dist"],
"main": "dist/index.js",
"scripts": {
"clean": "rm -rf dist",
"build": "npm run clean ; tsc"
},
"devDependencies": {
"typescript": "^4.3.4"
}
}
nameでimportする際のモジュールの名前を指定します。例のように階層を定義した場合、モジュールはnode_modules/anymind/module3に配置されます。filesにnpm install時にインストールされるファイルまたはディレクトリを指定します。dist配下のファイルのみ必要なので、distと指定します。mainで指定されたファイルにあるモジュールを、モジュールの呼び出し側は、nameで指定したpathからモジュールをimportすることができます。
(例)mainでモジュールのpathを指定することで、以下のようにコンパクトに記述することが可能です。
module3/package.json
{
"main": "dist/index.js"
}
module3/dist/index.js
export * from "./functions";
module3を呼び出す側
import { func1 } from "@anymind/module3";
// 以下と同様
import { func1 } from "@anymind/module3/dist/functions";
buildではtscコマンドを実行することでtypescriptをjavascriptにコンパイルします。
package.jsonの設定(Main Repository、Module1、Module2側)
弊社ではBitBucketをリポジトリ管理ツールとして使用しているので、package.jsonのdependenciesには以下のように記載します。
Module1のmasterブランチを使用する際は#masterのようにハッシュをリポジトリ名の後に付与します。
参考: Private NPM Packages in Bitbucket
Main Repository
{
"dependencies": {
"@anymind/module1": "bitbucket:adasiaholdings/module1#master",
"@anymind/module2": "bitbucket:adasiaholdings/module2#master"
}
}
Module1
{
"dependencies": {
"@anymind/module3": "bitbucket:adasiaholdings/module3#master"
}
}
Module2(Module1と同様)
{
"dependencies": {
"@anymind/module3": "bitbucket:adasiaholdings/module3#master"
}
}
以上のように設定することで、異なるリポジトリ内で作成したモジュールを呼び出すことができます。