typescript導入したprivateなnpmパッケージの作り方
はじめに
開発の規模を大きくなってくると、共通化したコンポーネントを利用したいこともあると思います。
git submoduleをつかって共通部分を切り出すことも可能ですが、branchの変更忘れてしまうと反映されないので、個人的には好みではないです。 一方privateなnpmパッケージで実現することも可能だと思います。
npm private registoryを利用することも可能ですが、こちらの場合 US $7/月という月額料金がかかってしまいます。 一方、github privateは無料になったので、githubをつかってprivate npmパッケージを作ってみたいと思います。
また共通利用するなら型情報があったほうがありがたいので、typescriptを導入してみたいと思います。
目標
1. my private npm moduleの作成
npm moduleの作成
共通ライブラリのnpmパッケージを作っていきます。
- npm moduleの作成
mkdir myNpmModule cd myNpmModule git init npm init -y
.gitignoreの設定は割愛します。
- typescript設定
npm i -D typescript npx tsc --init
npx tsc --init
で自動生成された.tsconfig.jsonに以下追加してコンパイル設定を修正する。
.tsconfig.json
{ ... "declaration": true, "sourceMap": true, "outDir": "./build", "rootDir": "./src", ... }
rootDir
でbuild対象のファイルを指定し、outDir
でbuild後のファイル保存先を指定する。
declaration
でビルド時にxxx.d.tsとして型定義ファイルを出力させる。
sourceMap
でtsとjsの対応関係をつくっておく。
- package.json修正
共通ライブラリの設定を追加します。
package.json
{ ... "main": "build/index.js", "files": [ "build" ], "scripts": { "build": "tsc", "prepare": "npm run build" }, ... }
files
ではパッケージ利用側にどのディレクトリ・ファイルをダウンロードさせるかを指定できる。
ただし、package.jsonとREADME.mdは指定しなくてもダウンロードされる。
main
でパッケージ利用側がimportコマンドを使用したときにどのファイルをロードするのかを指定する。
scripts
では、typescriptのbuildコマンドに加えて、 prepare
を設定する。
prepare
はパッケージ利用側が、パッケージをインストールする直前に実行させる処理を定義できる。
srcからビルドされたファイルを作成してくれるため、パッケージ管理側はbuildファイルをgit管理しなくてよい。
つまり、利用側で勝手にsrcからbuildディレクトリを生成してくれるため、.gitignoreにbuildディレクトリを指定しなくてよいわけとなります。
- 公開モジュール作成
mkdir src touch src/Person.ts
src/index.ts
class Person { private name: string; private age: number; public constructor(name: string, age: number) { this.name = name; this.age = age; } public call(): string { return this.name; } } export { Person };
git add . git commit -m 'my first commit';
github private repoとして登録
githubページより、新しいリポジトリ作成から、privateにチェックをつけて作成する.
git remote add origin git@github.com:karuta0825/myNpmModule.git git push -u origin master
buildディレクトリ管理しなくてよしです。
2. 他のリポジトリからimport確認
package.json
{ "dependencies": { ... "myNpmModule": "git+ssh://git@github.com:karuta0825/myNpmModule.git", ... }, }
利用側のpackage.jsonのdepenenciesで、使用したいprivate moduleを指定する。git+ssh//に続けて、githubのclone or dowloaddに表示されているパスをコピーすればよき。
npm i
を実行すると、node_modulesに作成したprivate packageが作成されてます。
. ├── node_modules │ ├── @types │ ├── myNpmModule <-- 追加されてる │ └── typescript ├── package-lock.json ├── package.json ├── sample.ts └── tsconfig.json
node_modulesのmyNpmModuleのディレクトリ構成も設定したとおり。
myNpmModule ├── build │ ├── index.d.ts │ ├── index.js │ └── index.js.map └── package.json
package.jsonのfilesに指定したbuildディレクトリのみがあり、そこには、型定義ファイルのindex.d.tsとコンパイルされたjsとsourceMapの.mapファイルがある。
では、実際にインストールした共通パッケージを利用できるか確認してみます。
importでき、候補も表示されています。
3. my npm moduleをバージョン管理する
共通パッケージを使用していくならば、バージョン管理をしておくも考えられると思います。
ということで、npmのバージョン管理設定も説明しておきます。
とっても簡単。commit後に npm version
を使用するだけです。
import dayjs from "dayjs"; class Person { private name: string; private age: number; public constructor(name: string, age: number) { this.name = name; this.age = age; } public call(): string { return this.name; } // 追加 public tellBirthYear(): string { return dayjs().subtract(this.age, "year").format("YYYY"); } }
git commitする
git add . git commit -m 'add a method to Person class.'
npm versionのあとに、major, minor, patchのいずれかを指定できます。
majorだと、1.0.0 => 2.0.0
minorだと、1.0.0 => 1.1.0
patchだと、1.0.0 => 1.0.1
にバージョンが変わる。
package.jsonのversionや、git logが変更されていること確認できます。
npm version minor git log --oneline // 6a0bb79 1.1.0 // 3d505ff add a method to Person class. // 351675f my first commit
package.json
{ ... "version": "1.1.0", ... }
git pushして、利用側でnpm updateをして確認すると、
npm update + myNpmModule@1.1.0 added 1 package from 1 contributor, updated 3 packages and audited 5 packages in 19.281s found 0 vulnerabilities
1.1.0のmyNpmModuleが利用できるようになりました。
実際下図の通り、追加したメソッドが候補に上がるようになります。
まとめ
github privateを利用して、typescript導入npmパッケージを作成しました。
また npm version
を利用してバージョン管理する方法をかんたんに説明しました。
ライブラリとして使用されるならば、以下のことも今後対応方法見つけられたらと思ってます。
- パッケージのmin化 現状だとsrcのディレクトリ構成のままbuildディレクトができるので、一本にまとめたほうがよい。
- material-uiやlodashのようにmyNpmModue/Personみたいな感じでロードファイルを指定できる
参考にしたサイト
https://dev.classmethod.jp/articles/private-npm-modules-to-package-json/https://medium.com/cameron-nokes/the-30-second-guide-to-publishing-a-typescript-package-to-npm-89d93ff7bccd