はじめに
自作のReactコンポーネントやライブラリを再利用する際、ファイルのコピー&ペーストではなく、
npm install <ライブラリ名>でインストールできると嬉しいですね(気がします)。
でも、npmに登録すると、全世界に知られてしまうのでどうかと思っていました。
(npmは登録後72時間経過すると簡単に消せなくなるそうです。あの時の俺に言いたい。NPMにpublishしたら(ほぼ)消せないことを)
いい方法はないかと調べてみたところ、GitHub Packagesを使えば、npmでインストールできるようになるそうですので、やり方をまとめてみました。
- Github Actions を使い自動化する方法もあるようですが、ライブラリ用にビルド+
npm publishの方が直感的なのでこちらの手順を採用しました
概要
- ①
create-react-appでコンポーネントを作成-
npm startで動作確認
-
- ②rollup.jsでライブラリをビルド
- 公開するコンポーネントをexport
- ビルドスクリプトを作成
- ③GitHub Packagesへ登録
- Github パーソナル アクセス トークンの取得
- .npmrcファイルを追加し、リポジトリとトークンを設定
- ④(別プロジェクトで)登録したライブラリをインストールして動作確認
-
npm install @githubユーザ名/パッケージ名でインストール
-
手順
①create-react-app でコンポーネントを作成
以前に作った
名前表示アイコン コンポーネント
をそのまま利用します
実行してサンプル画面が表示されることを確認します
npm start
②rollup.jsでライブラリをビルド
ライブラリとしてパッケージングするためrollup.js(ES6ネイティブなモジュールバンドラ)をインストールします
npm i -D rollup rollup-plugin-delete rollup-plugin-peer-deps-external rollup-plugin-postcss rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-node-resolve
package.json のdevDependenciesは下記のようになります
"devDependencies": {
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-typescript2": "^0.34.1"
}
続いて、ビルド用のスクリプトを作成します。rollup.config.jsをプロジェクトのルートに作成し、下記の内容を記載します
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
import postcss from 'rollup-plugin-postcss';
import del from 'rollup-plugin-delete';
const packageJson = require('./package.json');
// eslint-disable-next-line import/no-anonymous-default-export
export default {
input: 'src/lib.ts',
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true,
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true,
},
],
plugins: [
del({ targets: 'dist/*' }),
peerDepsExternal(),
resolve(),
commonjs(),
typescript({
tsconfig: 'tsconfig.build.json',
useTsconfigDeclarationDir: true,
}),
postcss(),
],
};
-
input: 'src/lib.ts',ライブラリとしてエクスポートするファイル(この後追加)です。
このファイルで、公開したい機能をexportします -
output: [~]common.jsと、ESモジュール 両方から使えるようにパッケージングします。
file:~は出力するファイル名で、package.jsonで指定します(この後追加) -
tsconfig: 'tsconfig.build.json',ビルド用に別の設定ファイルを参照します(この後追加)
src/lib.tsを追加(公開する機能をexport)
パッケージに公開するコンポーネント(関数)をexportします
// Component
export { default as NameIcon } from './NameIcon';
// Function
export { default as iconMaker } from './iconMaker';
NameIconがコンポーネント、iconMakerは画像を作る非同期関数です
package.jsonに、出力するファイル名の追加
{
"name": "@<ユーザ名>/ライブラリ名"
"version": "0.0.1",
"private": false,
"main": "dist/lib.js",
"module": "dist/lib.es.js",
"files": [
"dist"
],
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"repository": "https://github.com/<ユーザ名>/name-icon-lib.git",
}
-
@<ユーザ名>/ライブラリ名ライブラリ名の前に、githubのユーザ名を追記します
-
"version": "0.0.1"ライブラリのバージョンです。セマンティックバージョニングに従うようにします。修正パッケージをGitHub Packagesに上げなおす際、バージョンを変えないと受け付けてくれません
-
"private": false,元々は
trueになっているので、falseに変更します。trueのままだと、パッケージとして公開できません -
"main": "dist/lib.js"commonjsモジュールのエントリーポイントファイルを指定します(パッケージのルートからの相対パス)
-
"module": "dist/lib.es.js"ESModuleのエントリーポイントファイルを指定します(パッケージのルートからの相対パス)
-
files配布するパッケージが含まれるフォルダを指定します
-
"publishConfig": {GitHub Packagesに登録するために記載します(書かないと、npmに登録される)
-
"repository": ~パッケージのリポジトリを記載します(無くてもよいですが、あれば配布したパッケージ側で知ることができます)
tsconfig.build.jsonを追加(ビルド用の設定)
rollup.jsでパッケージングするためのビルド設定tsconfig.build.jsonをプロジェクトルートに作成します
{
"extends": "./tsconfig",
"compilerOptions": {
"outDir": "dist",
"declaration": true,
"declarationDir": "dist",
},
"exclude": [
"node_modules",
"dist",
"build",
]
}
-
"extends": "./tsconfig",デフォルトの
tsconfig.jsonの設定を継承します -
"outDir": "dist",出力先を
distにします -
"declaration": true,型定義ファイルを作成します(exportしている型)
Rollup.jsでビルド(パッケージ用)
package.jsonのscriptsに、パッケージビルド用のコマンドを追記します
"scripts": {
// 省略
"build-lib": "rollup -c"
},
実行した結果、dist/lib.js, dist/lib.es.jsの2ファイルができたら成功です
$ npm run build-lib
> @murasuke/name-icon-lib@0.0.11 build-lib
> rollup -c
src/lib.ts → dist/lib.js, dist/lib.es.js...
created dist/lib.js, dist/lib.es.js in 1.8s
③GitHub Packagesへ発行
Github Personal Access Tokenを取得
-
GitHubの右上のアイコンをクリックしてメニューを表示し
Settingsをクリック -
画面左側メニューの一番下にある
Developer settingsをクリック -
画面左側メニューから
Tokens (classc)をクリックしてからGenerate new token (classic)をクリックする -
必要事項を入力して
Generate tokenをクリック。表示されたアクセストークンを控えます- Expiretion(有効期限): 30 (適宜必要な日数)
- Select scopes(アクセス範囲):
write:packagesにチェック(パッケージを登録するため)
.npmrcにトークンとパッケージ登録先(GitHub Packages)を設定
.npmrcをプロジェクトのルートに作成し、下記の内容を記載します
@<Githubユーザ名>:registry=https://npm.pkg.github.com/<Githubユーザ名>
//npm.pkg.github.com/:_authToken=<アクセストークン>
1行目:パッケージ登録を行うレジストリの登録
2行目:アクセストークンを記載することにより、パッケージ登録時にログインを不要とする
また、Personal Access Tokenはパスワードと同様に知られては困る情報ですので、
GitHubnに登録されないよう.gitignoreに.npmrcを追記します
パッケージを(GitHub Packages)へ発行する
npm publishを実行してGitHub Packagesに発行します
$ npm publish
npm notice
npm notice 📦 @murasuke/name-icon-lib@0.0.11
npm notice === Tarball Contents ===
npm notice 6.0kB README.md
~~~中略~~~
npm notice 1.6kB package.json
npm notice === Tarball Details ===
npm notice name: @murasuke/name-icon-lib
npm notice version: 0.0.11
npm notice filename: murasuke-name-icon-lib-0.0.11.tgz
npm notice package size: 194.4 kB
npm notice unpacked size: 805.1 kB
npm notice shasum: dce3dd569572309afb8852a1ea10346754ce027c
npm notice integrity: sha512-MYb/IinuMY8fD[...]Z3IHL6rgS4auQ==
npm notice total files: 12
npm notice
npm notice Publishing to https://npm.pkg.github.com/murasuke with tag latest and default access
+ @murasuke/name-icon-lib@0.0.11
④(別プロジェクトで)登録したライブラリをインストールして動作確認
登録したパッケージを別プロジェクトでインストールして利用します
npmコマンドで、GitHub Packagesを読み込めるよう設定する
.npmrcファイルを作成し、下記内容を記載します(インストール時は、アクセストークンは不要)
@<Githubユーザ名>:registry=https://npm.pkg.github.com/<Githubユーザ名>
npmコマンドで、パッケージをインストールします(パッケージ名の前に、をつけることで、GitHub Packagesから読み込まれます)
npm install <Githubユーザ名>:<発行したパッケージ名>
例
npm install murasuke/name-icon-lib
importする際、@<ユーザ名>/ライブラリ名で読み込んで使えます。
import { NameIcon, iconMaker } from '@murasuke/name-icon-lib';
const App = () => {
return (
<>
<NameIcon
userName="山田太郎"
option={{ foreColor: '#69C', backColor: '#FFF2F3', size: 80 }}
/>
</>
);
};
参考ページ





