🚀

AI 時代こそ npm publish !

に公開

AI 時代こそ npm publish !

みなさん、はじめまして!フロントエンドエンジニアの @nyaomaru です!

本格的な AI 時代が到来して、みなさんは如何お過ごしでしょうか?

僕はこの時代、めちゃくちゃワクワクしてます。
だって——個人開発、最強の時代が来たから!

今では、AI (今回の文脈では ChatGPT) とペアプロしながら、想像以上のスピードでアウトプットできるようになりました。
そのおかげで、仕事をしながらでも「自分が本当に作りたいもの」を形にするチャンスが増えてきたと感じています。

  • 短い時間でも創作できる。
  • 自己表現を、ちゃんとプロダクトとして出せる。

そんな時代だからこそ——
👉 OSS 作っていこな!

着想

ライブラリを作る上で必要なのは、「ほな、どんなライブラリ作ろか~?」という着想や。

それは、課題から始まってもいいし、全く突拍子もないことでもええ。とにかく「これ、ええんちゃうかな~?」と思うパッションが大事やな。

僕は課題から入ったタイプで、「分割処理って地味に毎回書いてない?」「これ、ユーティリティライブラリとして提供したら、誰かの役に立つんちゃうか!?」って考えたな。(まあ、自分のライブラリ作ってみたいという下心もあったけど。笑)

でも、ただ作るだけやったら車輪の再発明になるかもやから、「ネイティブの関数と比較してどうなん?」「それでも作る必要あるん?」「他のライブラリは?」ってな具合で、比較検討をしたほうがええ。

そこで、ChatGPT の出番や。

着想段階にあるライブラリが、世の中にあるものと被ってないか?作る意義はあるのか?を壁打ちして確認できるのは、本当に心強い。いっつもポジティブで、ええ友達やで、ホンマ。

その結果、「ええやん!」ってなったら、あとは形にするだけや!

設計

「ほな設計していこか~」となるわけやけども、具体的にどんなもの作るかはライブラリによって異なるから、あんまり詳細は書かへん。あくまでも汎用的な話だけに留めるで~。

個人開発のコードとはいえ、OSS として公開すると、世界中のみんなが見る可能性があって、その中で PR を作ってもらえたり、誰かが main contributor になってくれるかもしれへん。その時に共同開発しやすいような設計は必要やと思う。

せやから、Readability や Sustainability を意識して、人間の脳に収まるコードを書くことを主題に置くとええんちゃうかな?

具体的には以下のことを意識してるで~。(当たり前なんやけど、それが難しいねんなぁ・・・)

  • 命名
  • 明確な型
  • 責務分離
  • 小さな関数
  • 英語で説明を記載

ライブラリの規模にも寄るけど、monorepo にしたり、directory を階層化したりとかアーキテクト設計まで考える必要があるかもしれんけど、まずは上記のことを実現できていれば、共同開発で困ることはないんちゃうかな。

設計フェーズでも、ChatGPT は大活躍や。

自分で考えた設計を壁打ちしてもろて、共同開発にも耐えれるくらいの柔軟性と安定性のある設計を一緒に考えてもらお。

ホンマ、爆速でええ感じの設計できるから。マジで。

実装

設計が終わったら、「よっしゃ、開発するで~!」となるわけですが、レガシーなライブラリではなく、モダンなライブラリとして出すなら、しっかり選定しないとアカンやん、アカンやん。

そこで僕は wasmjavascript ではなく、typescript で実装することを選択しました。一番の理由は「typescript が好きやから」。それ以外の理由はぶっちゃけない。笑 (Rust で書く人は素敵やん?)

ほんで、次に周りの技術どうしよか~ってなったら、流行を確認してみよか~。

https://2024.stateofjs.com/en-US/

最近の使用技術を追って、良さそうなもの(おもろそうなもの)を選んだらええんちゃうかな?

ここでももちろん?ChatGPT や。

ChatGPT は流行には弱い部分もあるけど、ここでも考えた技術選定がいい組み合わせかどうかレビューしてもらお。

あと、実装のプロトを作るのはホンマにうまいから、設計した内容を具体にしてもらってから、一緒にブラッシュアップしていくのが爆速やな。注意せなあかんのは、一発目に出てくるのはあくまでも tactical な実装であって、strategic じゃないとこやな。つまり、とりあえず動くの作るのは得意やねんけど、そこまで構造化されてるわけやないってこと。

せやから、ここがエンジニアの腕の見せどころなんちゃうかな。設計した構成に合うように、そして human readable になるように改修して、さらに壁打ちすると、ええ感じのコードが仕上がってくるで~。一番おもろいとこやな~!

テスト

動くものだけあっても、持続可能性は低いやん?せやから、安定性を求めてテスト書こか~。

最低限、lint と unit test くらいあったら嬉しいわな。

linter は好きなの選んだらええ。Biome もええけど、eslint 好きやから eslint 選んだ!みたいな感じでええ。

unit test には、CJS も見越して jest 選んだ!とかでもええ。なんでもええから、テスト書くのが大事。

そこで、「BDD スタイル & AAA の記述方式は読みやすくてええな~」とか個人的には思うけど、そんなん好みの問題やし、記述方式よりも中身のほうが大事やから、別になんでもええ。

基本的には、作った関数にテストを作成して、Github Actions で PR の作成を hook にして実行するように CI/CD を組んでおくと、他の人が実装したときも安心やな。

さてここで、ChatGPT はどうなるとおもう?——もちろん、大活躍や!

既存のコードからテスト作るのはホンマにうまい。こんなん人間にはできひんってくらいうまい。やから任せよ。

ほんで、気になるケースだけ追加したらええ。エッジケースとかやりすぎる節があるから、ちょっと削ってもええ。もちろん、そのままあってもええ。

TDD で開発するときも、想定ケース洗い出せていればまず間違いなく作ってくれる。ホンマにうまい。

テストはホンマに任せよ。エグいから。マジで。

npm パブリッシュの流れ

ここまできたら、もうライブラリを publish する準備はできてるはずや。

僕の場合は、tsup で ESM と CJS に対応した .d.ts と runtime の js を吐き出すようにしたけど、build できたらなんでもええ。でも、型はあったほうが利用者は絶対嬉しいから、できたら追加しとこな。これは約束やで。

setting

ほんで package.json にこんな感じで書いとくとええな~。

"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
    "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js"
    },
    "require": {
        "types": "./dist/index.d.cts",
        "default": "./dist/index.cjs"
    }
},

さらに、github actions で、release の tag 作ったら、自動で npm publish されるように組んどいたら、めっちゃ楽ちんや。

以下の情報はあったほうが嬉しいから、できれば package.json に記載したほうがええな。

  • keywords: npm 内での検索ワード
  • repository:
    • type: git
    • url: repository の url
  • homepage: ホムペ作ってあったら、見やすくって嬉しいわな
  • author: 作者書いとくと、誰が作ってん?ってなっても困らへんな
  • license: 再配布可能なのか知りたいときもあるから明示したほうがええな
  • bugs:
    • url: issue の link を貼っておくと、追いやすくてええな~

license

ほんで、パブリッシュする前に要注意や!

「ライセンスはちゃんと書こな」

利用する人が、これって勝手に使ってええんやろか?怒られるんちゃうかな・・・?って不安になるからな。

MIT License / Apache License 2.0 / MS-PL とか色々あるけど、基本再配布 OK なら MIT でええと思うで。ほんで、ライセンスファイルを root directory に置いとくと、利用者側は安心や。ここまではやっといたほうがええと思うで~。

publish

あと、ライブラリの公開には、public と private の二種類があるんや。

世界的に公開してもええなら public でええし、特定のチームや組織だけで利用したいなら、 private で公開するねん。

そして、ライブラリの名称にも Non-Scoped と Scoped の二種類があるねん。

Non-Scoped はそのままライブラリ名を公開する感じやな。 zod とか react とかは Non-Scoped やね。

ほんで、prefix に名称を付けたい場合や、ライブラリの名称を一意にしたい場合は、Scoped にする。例えば、@tanstack/react-query や、@radix-ui/react-*も Scoped やね。

基本的には public かつ Non-Scoped でええと思う。やけど、たまに公開しようとしたライブラリ名が被ってたりしたり、組織としてライブラリを管理したいときには、Scoped を利用する感じやな。

ほんで

ほんでいよいよ publish するってなったら、ChatGPT の出番や!

まずは、package.json の内容やライセンスについて、レビューしてもらお。ミスったら大変やねんけど、煩雑やからな。このへん、うまいことやってくれるねんな~。ホンマええ子やで。

コマンドも全部教えてもらお!注意せなアカンのは、Scoped のライブラリの場合は

npm publish --access=public

のようにするか、.npmrcaccess=publicを記載する必要があるで~。(コマンドの場合、初回のみ必要で、2 回目以降は不要や!)

ほんで、最後は勇気の publish や!なんか起こったら、後で直せばええねん。それでええ

運用とこれから

公開して終わりじゃアカン。利用する人がいるんやから、定期的にリファクタリングしたり、依存するライブラリをアップデートしたり、思いついた新しい機能追加したり、やることはたくさんある。

これから何しよ?って困ったら、ChatGPT

新しい機能実装しよ!って思ったら、ChatGPT

人生どないしよ、ホンマ。って涙したら、ChatGPT

何が言いたかったかというと、パッションがあれば OSS として自己表現できるということ。

適切に AI と付き合うことで、自分の能力を加速させることができる一方、うまく使えないとあまり役に立たへん。つまり

自分が成長しないと、AI を最大限に利用できない

ということ。ここが大事なポイントや。やから、一緒に成長していくのが一番ええと思う。

その点においても、ChatGPTは素敵な相棒や。いっぱい協力して、色んな事していったらええんちゃうかな?知らんけど

宣伝 ①

文字列や配列の分割、地味に毎回書いてへん?
そこで、divider っていう文字列と配列を分割するユーティリティライブラリを作ってみたから、みんな寄って見てって~!
気に入ったら してな!

🔗 GitHub: nyaomaru/divider
🎮 Playground: divider-docs.vercel.app

divider の Playground もあるから、よかったら遊んでってな~

宣伝 ②

qiita でも記事書いてるから、良かったら見てってな~!

https://qiita.com/nyaomaru/items/1c250e68b319719de844

Discussion