Closed7

気になっているフロントエンドのエコシステムに触れる

Tashiro YutakaTashiro Yutaka

pnpm

https://pnpm.io/ja/

メモ

高速に動作する理由。

  1. 異なるバージョンのパッケージに依存している場合は、更新されたファイルのみがストアに追加されます。たとえば、100 個のファイルがある依存において、 新しいバージョンがそれらのファイルのうち 1 つだけに変更を加えた場合、 pnpm update は存関係全体を複製するのではなく、ストアにその新しいファイルのみを加えます。
  2. すべてのファイルは、ディスク上の 1 つの場所に保存されます。 パッケージが インストールされると、そのパッケージのファイルは 1 か所からハードリンクされ、追加のディスク領域を消費しません。 これにより、同じバージョンの依存をプロジェクト間で共有できます。
  • node_modules/.pnpm/ 配下にパッケージの実態がまとまっている。(参考
    • あるパッケージをインストールしたときに、npm ならそのパッケージの依存パッケージが node_modules/ 直下にフラットに展開される。
    • pnpm では node_modules/.pnpm/ に依存パッケージが展開され、node_modules/ 直下は追加したかったパッケージのみが展開される。
      • また、node_modules/ 直下に展開されるパッケージは node_modules/.pnpm/ 配下の実態へのシンボリックリンクになっている。(参考
  • pnpm の厳格さの理由
  • Node.js v16.13 からパッケージマネージャーのバージョン管理をする Corepack が提供されているので pnpm のバージョン管理に利用する。
  • npm, yarn との比較
  • よく利用するコマンドの対応表
    • npm cipnpm i --frozen-lockfile
  • package.json で pnpm.overrides を指定すると全てのパッケージが同じバージョンの依存パッケージを使うように強制したりできる。(リファレンス
  • ワークスペースプロトコル(workspace:)で指定されたパッケージは必ずローカルで解決される。(リファレンス
  • pnpm --filter ${packageName} で指定のパッケージに対してコマンドを実行できる。
    • web パッケージの dev コマンドを実行。
      $ pnpm --filter web dev
      
    • ui パッケージに react を追加。
      $ pnpm add --filter ui
      
    • ルートパッケージから babel-loader を削除。(-w オプション)
      $ pnpm rm -w babel-loader
      

.npmrc

https://pnpm.io/ja/npmrc

  • enable-pre-post-scripts=true を指定しないと pre, post のプレフィックスが付与されたスクリプトを実行しない。
  • hoist
    • 依存を node_modules/.pnpm に巻き上げるかの設定。
  • hoist-pattern
    • どのパッケージを node_modules/.pnpm に巻き上げるかの設定。デフォルトは全てのパッケージ。
  • public-hoist-pattern
    • どのパッケージを node_modules に巻き上げるかの設定。デフォルトは ['*eslint*', '*prettier*'] のパッケージ。
    • eslint, prettier, storybook などの多くの依存があるパッケージのパターンを指定することで、依存をすべて package.json に記述しなくても、依存を解決してくれる。
      • storybook の addon は種類が多く全てインストールすると管理が面倒なのでパターンを追加しておくと良さそう。
      .npmrc
      public-hoist-pattern[]=@storybook/addon-*
      
  • shamefully-hoist
Tashiro YutakaTashiro Yutaka

turborepo

https://turbo.build/repo/docs

特徴

  • JavaScript / TypeScript の高性能なビルドシステム
  • 特徴
    • 差分ビルド
    • コンテンツをハッシュにして差分があるか検証する
    • 並列実行、CPUがアイドル状態にならないように
    • ランタイム、ソースコードに干渉しない
      • プラガブルなアーキテクチャで良いと思った
    • タスクの依存関係をパイプラインとして定義できる
    • リモートにキャッシュを配置することも可能

設定

チュートリアルから移植するのがイメージしやすいためやってみる

$ npx create-turbo@latest

メモ

Tashiro YutakaTashiro Yutaka

monorepo

特定の技術ではないが monorepo について書く。

メモ

  • フロントエンドの設計をしっかり考えなければいけなくなるので難しい。
  • ビルド、テスト、Lint の設定が複雑になる。
  • 色々新しい技術に触れるのは楽しい。

TypeScript, ESLint

  • @ から始まる alias の設定を tsconfig.json に定義して vite, eslint からは tsconfig.json の設定を参照してパスを解決するようにする。

要確認

eslint-plugin-import

no-unresolved

Q. package.json の export. 以外は実態と異なるパスを指定するパスが解決できず ESLint エラーが発生する?

package.json
{
...
  "exports": {
    ".": "./dist/index.js", // OK
    "./dist/*": "./dist/*", // OK
    "./lib/*": "./dist/*" // NG
  }
...
}

A. 実行時は動作するが、ESLint のプラグイン eslint-plugin-import の対応が追いついていないためエディターではエラーが表示される。

vite でアプリケーションを起動して ESLint のプラグインも導入しているがなぜ実行時はエラーにならず動作するのか不明。

参考:https://github.com/import-js/eslint-plugin-import/issues/2389

Tashiro YutakaTashiro Yutaka

peerDependencies

monorepo の構築やライブラリの開発を今までしてこなかったので、あまり知らなかった。
npm のドキュメントの翻訳を見ても分からなかったのでこちらの記事で理解した。

必要になるのは「プラグインモジュール」と「シングルトンモジュール」として扱う場合。

  • プラグインモジュール
    • 単体では機能せず、メインとなるパッケージのインストールが必須であることを明示したい場合。
  • シングルトンモジュール
    • あるモジュールがアプリケーション全体で一つであるようにしたい場合。

https://pnpm.io/ja/how-peers-are-resolved

  • pnpm では peerDependencies を依存関係のセットごとにインストールする?

https://pnpm.io/ja/package_json#pnpmpeerdependencyrulesignoremissing

指定した項目の peerDependencies が存在しなくても警告を無視する。

{
  "pnpm": {
    "peerDependencyRules": {
      "ignoreMissing": ["@babel/*", "@eslint/*"]
    }
  }
}
Tashiro YutakaTashiro Yutaka

pnpm の機能で eslint を public-hoist しないと VSCode の ESLint 拡張機能が動作しないことがあるので、eslint 関連は public-hoist した方が良さそう。

VSCode の ESLint の出力を見ると依存パッケージが見つからないなどのエラーが表示されていた。

Tashiro YutakaTashiro Yutaka

tsup

  • セットアップに手間がなく開発体験が良かった。
  • (体感だが)動作も高速だった。
このスクラップは2024/01/21にクローズされました