フロントエンドとバックエンドで共通のファイルをGitHub Packagesで共有する
February 2, 2022
例えばフロントエンドとバックエンドの両方を TypeScript で開発している場合、型定義を共有したい場面があるはず。
両方に同じコードをコピペすることで当座は解決はできますが、長期的に考えるのであれば同じ1つのファイルを参照するようにしておくべきです。
方法はいろいろありますが、ここでは共通するコードを別のパッケージとして開発し、それを GitHub Packages を通じて利用する方法をご紹介します。
まず、パッケージを作成・更新する側の流れを書き、次に、そのパッケージを利用する側の流れを記述します。
パッケージを作成・更新する #
1. GitHub のリポジトリを作成する #
以降 “harry-potter” という GitHub アカウントのユーザで操作すると想定します。
ここでは harry-potter/example-core
というリポジトリを作成しました。
2. パッケージを作成する #
ファイルを用意する #
まずはパッケージの元となるファイルを作成します。
全体の構成
├ node_modules/
├ package.json
├ tsconfig.json
├ .gitignore
└ src/
└ index.ts
package.json
{
"name": "@harry-potter/example-core",
"version": "0.0.1",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": ["dist"],
"devDependencies": {
"typescript": "^4.0.0"
},
"scripts": {
"build": "tsc"
}
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist",
"target": "ES2015",
"module": "commonjs",
"sourceMap": true,
"declaration": true,
"declarationMap": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
.gitignore
node_modules/
dist/
src/index.ts
export type Summable = [number, number];
export function sum([a, b]: Summable): number {
return a + b;
}
ビルドする #
npm run build
dist
ディレクトリにビルドされたファイルが作成されます。
└ dist/
├ index.js
├ index.js.map
├ index.d.ts
└ index.d.ts.map
3. GitHub のアクセストークンを生成する #
GitHub Packages にパッケージをパブリッシュするために GitHub のアクセストークンが必要になります。
GitHub の以下からアクセストークンを生成します。
> Settings
> Developer settings
> Personal access tokens
> Generate new token
トークンの名称と権限のスコープを指定する必要があります。
- 名称:お好みで。例えば
GitHub Packages
で良いでしょう。 - 権限のスコープ:
write:packages
を選択します。この権限を選択すると、他に必要な権限(repo)も付随して自動的に選択状態になります。
4. .npmrc を設定する #
├ dist/
├ node_modules/
├ package.json
├ tsconfig.json
├ .gitignore
├ .npmrc
└ src/
└ index.ts
上記の通り .npmrc
を新規作成します。そして以下のように記載してください。
.npmrc
@harry-potter:registry=https://npm.pkg.github.com/harry-potter
//npm.pkg.github.com/:_authToken=ghp_acbdefghijklmnopqrstuvwxyz0123456789
_authToken
には先の手順で生成した実際のトークンを設定してください。
5. npm publish する #
npm publish
を実行します。
npm publish
これでパッケージはパブリッシュされました。
GitHub のページを開くと、Packages のところが更新されていることがわかります。
Packages(画像の右下)
6. パッケージを更新する場合 #
コード変更と合わせて package.json
の version
をあげてからビルドし npm publish
します。
// 変更前
"version": "0.0.1",
// 変更後
"version": "0.0.2",
補足:万が一にも npmjs にパブリッシュしないために #
これまでの方法だと .npmrc
が存在しない場合には自動的に npmjs にパブリッシュする動きをします。
GitHub Packages 以外への誤ったパブリッシュを避けるためには package.json
に以下の設定を加えておきましょう。
package.json
{
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
}
}
パッケージを利用する #
1. .npmrc を作成する #
パッケージを利用したいリポジトリの中に、先ほど作成した .npmrc をコピー作成します。
2. インストールする #
package.json
に先ほど作成したパッケージ名とそのバージョンを指定してインストールします。
{
"dependencies": {
"@harry-potter/example-core": "0.0.1"
}
}
npm i
3. 使用する #
後は通常のパッケージと同様に利用するだけです。
import { sum } from '@harry-potter/example-core';
import type { Summable } from '@harry-potter/example-core';
const nums: Summable = [1, 2];
sum(nums); // 3
補足:.npmrc に利用するユーザについて #
上記ではパッケージ利用者側の .npmrc にパッケージ開発者と同じものをコピペして使用しました。
この場合、パッケージ利用者もこのアクセストークンを利用することでパッケージを更新することが可能です。
利用者にパッケージ更新の権限を与えたくない場合は、別のアクセストークンを発行してそちらを利用者の .npmrc に適用するようにします。
その場合は read:packages
を与えたアクセストークンを作成しましょう。
参考 #
Working with the npm registry
パッケージのリポジトリをモノリポで作成している場合は以下の記事が参考になります。
https://dev.classmethod.jp/articles/github-packages-private/