はじめに
- TypeScriptで自分用のライブラリを作って再利用したい
- npmリポジトリには公開しない
- なのでローカル/GitHubから
npm install
したい - 型定義も保持したい
ということを思ったのですがやり方が分からなかったので調べました。
プロジェクトを初期化する
なにはともあれnpm initから始めていきます。
$ npm init
$ npm install typescript
$ tsc --init
次にtsconfig.jsonを編集します。
基本的にお好みですが、大事なポイントとして"declaration": true
にして型定義ファイル*.d.ts
が生成されるようにしておきます。
またコンパイル結果をまとめたいので"outDir": "./dist"
を定義します。
ソースコードもsrcディレクトリに置きたいので"include": ["src/*"]
を定義しておきます。
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"newLine": "lf",
"pretty": true,
"outDir": "./dist",
"strict": true,
"skipLibCheck": true
},
"include": "src/*",
"exclude": "src/test*"
}
ライブラリを実装する
方向性としてモジュールを分割して作ることが多いと思うのでそれぞれファイルを分けてみました。
ここらへんはやりたいようにやればいいと思います。
export type Person = {
name: string;
age: number;
};
import { Person } from './types';
export function hello(person: Person): void {
console.log(Hello, ${person.name}(${person.age})!);
}
import { Person } from './types';
export function bye(person: Person): void {
console.log(Bye Bye, ${person.name}(${person.age})!);
}
npmで利用するためには後述のpackage.jsonでエントリポイントの設定をする必要があります。
エントリポイントは最初に呼び出されるモジュールの指定ですが、基本的に1ファイルしか指定できないため上記のコードも1つにまとめておく必要があります。
まとめ方は色々あるかと思いますが、webpackなどのモジュールバンドラーを使わないのであればindex.tsを作って必要な分だけexportする方法がシンプルかと思います。
export * from './hello'
export * from './bye'
export * from './types'
コードができたのでコンパイルしましょう。
$ tsc
distディレクトリを見るとindex.js
とindex.d.ts
が出来ていますのでpackage.jsonに設定します。
これでexportした関数などを外部からをimport出来るようになります。
{
"name": "greeting", // モジュール名、importで呼び出す時の名前になる
~~略~~
"main": "dist/index.js", // 最初に呼び出されるモジュール
"types": "dist/index.d.ts", // 型定義
"private": true // npmパッケージを公開しないため念の為privateに
}
これでライブラリが完成しました。
npmでinstallしてみる
npm installする時、ライブラリをどこに置いておくかという話ですが、自分用なのでローカルかGitHubが良さそうです。
ローカルの場合
さっき作ったpackage.jsonがあるディレクトリのパスを指定すれば可能です。
テスト用に新しくプロジェクトを作成するなどして試してみましょう。
$ npm init
$ npm install ../greeting // ライブラリのあるパスを指定
読み込み側のpackage.jsonを見ると下のような感じで読み込まれます。
ちなみにnode_modulesに作られるのはコピーではなくシンボリックリンクなので変更とかには注意が必要です。
"dependencies": {
"greet": "file:../greeting",
}
試しにimportしてみるとちゃんとhello関数が読み込めることが分かります。
import { hello } from 'greet'
hello({name: 'Hanako', age: 18});
$ tsc
$ node dist/sample.js
Hello, Hanako(18)!
GitHubの場合
基本的には同じでURLでinstallできます。
他にもブランチ指定したりSSHも使えるようなのでよっぽどじゃない限り足りると思います。
$ npm install https://github.com/{username}/{repo}
"dependencies": {
"greet": "git+https://github.com/{username}/{repo}.git",
}
参考:
https://qiita.com/pure-adachi/items/ba82b03dba3ebabc6312
https://qiita.com/saltyshiomix/items/d889ba79978dadba63fd