npmパッケージの作成と公開/更新に便利(なはずの)boilerplateを作ったので
以前作ったuseStackRefをnpmパッケージとして公開してみる
最終結果
https://github.com/nariakiiwatani/react-use-stack-ref
https://www.npmjs.com/package/react-use-stack-ref
この記事にしたがって進めていく
https://qiita.com/nariakiiwatani/items/ac8acb1822ead4dfc429
ダウンロード
dev-npm-package-react-typescript-boilerplateをZIPでダウンロードして適当なフォルダに解凍する。
package.json
を編集
"name": "react-use-stack-ref",
"author": "nariakiiwatani <nariakiiwatani@annolab.com> (https://github.com/nariakiiwatani)",
"repository": {
"type": "git",
"url": "git+https://github.com/nariakiiwatani/react-use-stack-ref"
},
開発環境のセットアップ
あとでyarn run setup:demo
をやることになるのでここは単にyarn run setup
でも良かった
yarn run setup:all
yarn run v1.22.4
$ yarn run setup && yarn setup:demo
$ yarn install
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
$ cd demo && yarn install
warning package.json: No license field
warning No license field
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
✨ Done in 15.39s.
src
フォルダ内を編集
-
ModuleFile.ts
削除 -
useStackRef.ts
を作成 -
index.js
とindex.d.ts
を修正
import { useStackRef } from './dist/useStackRef'
export { useStackRef }
ビルドが通るか確認
yarn run build
yarn run v1.22.4
$ tsc
✨ Done in 1.74s.
dist
フォルダにビルド結果が出力されていることを確認

コミットしておく
ここで、編集を始めるより前に初期状態をコミットしておいた方が良かったと後悔する
git init
git add .
git commit -m "initial commit"
[master (root-commit) 5ab56bf] initial commit including new module 'useStackRef'
19 files changed, 8973 insertions(+)
create mode 100644 .github/workflows/pages.yml
create mode 100644 .github/workflows/release.yml
create mode 100644 .gitignore
create mode 100644 LICENSE.md
create mode 100644 README.md
create mode 100644 demo/.gitignore
create mode 100644 demo/dist/index.html
create mode 100644 demo/package.json
create mode 100644 demo/src/components/App.tsx
create mode 100644 demo/src/index.tsx
create mode 100644 demo/tsconfig.json
create mode 100644 demo/webpack.config.js
create mode 100644 demo/yarn.lock
create mode 100644 index.d.ts
create mode 100644 index.js
create mode 100644 package.json
create mode 100644 src/useStackRef.ts
create mode 100644 tsconfig.json
create mode 100644 yarn.lock
デモページのセットアップ
"dependencies": {
"react-use-stack-ref": "link:../"
},
import { useStackRef } from 'react-use-stack-ref'
yarn run setup:demo
yarn run v1.22.4
$ cd demo && yarn install
warning package.json: No license field
warning No license field
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
✨ Done in 9.92s.
デモページのビルドを確認
yarn run build:demo
yarn run v1.22.4
$ cd demo && yarn run build
warning package.json: No license field
$ webpack
Hash: 60733be7b91f6c1ca0c1
Version: webpack 4.44.1
Time: 2151ms
Built at: 2020-08-12 16:28:08
Asset Size Chunks Chunk Names
bundle.js 947 KiB main [emitted] main
bundle.js.map 1.08 MiB main [emitted] [dev] main
Entrypoint main = bundle.js bundle.js.map
[0] multi ./src/index.tsx 28 bytes {main} [built]
[./src/index.tsx] 179 bytes {main} [built]
+ 12 hidden modules
✨ Done in 3.35s.
demo/dist
フォルダに結果が出力される

開発用サーバーでデモページが動作することを確認する
yarn run dev
yarn run v1.22.4
$ yarn run build
$ tsc
$ cd demo && yarn run start
warning package.json: No license field
$ webpack-dev-server --open
ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from ./dist
ℹ 「wdm」: wait until bundle finished: /
ℹ 「wdm」: Hash: e51f0a781a90c74c170f
Version: webpack 4.44.1
Time: 2518ms
Built at: 2020-08-12 16:29:27
Asset Size Chunks Chunk Names
bundle.js 1.26 MiB main [emitted] main
bundle.js.map 1.46 MiB main [emitted] [dev] main
Entrypoint main = bundle.js bundle.js.map
[0] multi (webpack)-dev-server/client?http://localhost:8080 ./src/index.tsx 40 bytes {main} [built]
[../node_modules/react-dom/cjs/react-dom.development.js] 839 KiB {main} [built]
[../node_modules/react-dom/index.js] 1.33 KiB {main} [built]
[../node_modules/react/index.js] 190 bytes {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 4.29 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2.91 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built]
[./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built]
[./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./src/components/App.tsx] 135 bytes {main} [built]
[./src/index.tsx] 179 bytes {main} [built]
+ 31 hidden modules
ℹ 「wdm」: Compiled successfully.
空っぽのページがブラウザで表示される。コンソールにエラーもなし。

デモページを作成
import React, { useState, useCallback, ChangeEvent } from 'react'
import { useStackRef } from 'react-use-stack-ref'
const App = (props: {}) => {
const stack = useStackRef()
const [input, setInput] = useState("")
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value)
}
const handlePush = useCallback(e => {
stack.push(input)
setInput("")
}, [stack])
const handlePop = useCallback(e => {
const value = stack.pop()
value && setInput(value as string)
}, [stack])
return (<>
<h1>live demo for useStackRef</h1>
<input type="text" value={input} onChange={handleChange} />
<button onClick={handlePush} disabled={input.length === 0}>push</button>
<button onClick={handlePop} disabled={stack.size === 0} >pop</button>
<div>current value: {stack.value}</div>
<div>stack depth: {stack.size}</div>
</>)
}
export default App;
動作確認

コミットしておく
git add .
git commit -m "create demo"
[master 5d27f8f] create demo
3 files changed, 34 insertions(+), 14 deletions(-)
rewrite demo/src/components/App.tsx (65%)
GitHubリポジトリを設定
react-use-stack-refという名前のリポジトリを作成
npmのサイトでnpmトークンをRead and Publish
の権限で作成
クリップボードにコピーしておく

GitHubリポジトリのSettings -> Secrets
に新たな変数を追加
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
の部分はコピーしたトークン文字列

追加後の画面

README.md
を編集してコミット
git add .
git commit -m "update readme"
[master 5c9508f] update readme
1 file changed, 37 insertions(+), 95 deletions(-)
rewrite README.md (99%)
git push
git remote add origin git@github.com:nariakiiwatani/react-use-stack-ref.git
git push -u origin master
Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Delta compression using up to 8 threads
Compressing objects: 100% (31/31), done.
Writing objects: 100% (38/38), 148.32 KiB | 898.00 KiB/s, done.
Total 38 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:nariakiiwatani/react-use-stack-ref.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
GitHub Pagesの設定
Publish demo page
というGitHub Actionが自動で実行されて、デモページのビルド結果がgh-pages
ブランチのpushされる。
するとリポジトリのSettings -> Options -> GitHub Pages
でgh-pages
が選べるようになるので選択して、ディレクトリは/(root)
のままでSave
ボタンを押す

動作確認
公開用URL( https://nariakiiwatani.github.io/react-use-stack-ref/ )でデモページが動いていることを確認

デモのページをREADMEに追記しておく
[live demo](https://nariakiiwatani.github.io/react-use-stack-ref)
git add .
git commit -m "add live demo url in readme"
[master f156883] add live demo url in readme
1 file changed, 2 insertions(+)
git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 361 bytes | 361.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:nariakiiwatani/react-use-stack-ref.git
5c9508f..f156883 master -> master
npmのサイトに行ってパッケージが公開されていることを確認
...ない!

GitHub Actionのログを確認
semactic-releaseが新しいバージョンがないと判断してpublishしなかったらしい
[8:02:52 AM] [semantic-release] › ✔ Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[8:02:52 AM] [semantic-release] › ℹ There are no relevant changes, so no new version is released.
semantic-releaseのために何かコミットしてpush
READMEにnpmパッケージページへのリンクを記載した。
コミットメッセージを"fix:"で始めるのを忘れない。
git add .
git commit -m "fix: add npm site in readme"
[master fbb5d05] fix: add npm site in readme
1 file changed, 2 insertions(+)
git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 336 bytes | 336.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:nariakiiwatani/react-use-stack-ref.git
f156883..fbb5d05 master -> master
公開確認!

終わりに
ということで、semantic-release
の仕様を忘れていた以外は特につまづくことなく公開できました。
今回はデモページの作成やこの記事のための記録があってトータルで30〜40分くらいかかりましたが、新しいパッケージの開発環境構築と公開に限って言えば余裕で30分を切るのではないでしょうか。
みなさんもどうぞ自分のライブラリを公開する際は使ってみてください。