はじめに
はじめまして、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"
}
}
以上のように設定することで、異なるリポジトリ内で作成したモジュールを呼び出すことができます。