Help us understand the problem. What is going on with this article?

Berry(yarn v2) + TypeScript + PnP + Workspace でプロジェクトを作ってみた感想

berry(yarn v2) がそろそろリリースということで、使い込んでみた。その感想や yak-shaving などについて。

このリポジトリ https://github.com/mizchi/berry-typescript-project

日本語での網羅的な解説はこちらの記事がくわしい https://qiita.com/dojineko/items/6f65fde3c47aed8b6318

本記事は pnp の仕組みと webpack, jest, typescript を設定する泥臭い話がメイン。

使ってみた感想

  • npm とは完全に別系統に進化しつつある。互換があんまりない。
  • 今対応するのは時期尚早でアーリーアダプターだけでよい
  • berry 自体が typescript で書かれているので、typescript 連携は揃っている。ただし @arcanis 氏の手が届く範囲で。
  • pnp 対応でエコシステム全部見直す必要があり大変
  • workspaces 対応は素晴らしいので使っていきたい

pnp とは

https://classic.yarnpkg.com/en/docs/pnp/

node_modules にすべてのファイルを展開するのではなく、 .yarn/cache に zip ファイルを置く。なんやかんやあって hot cache で最大70% 速くなると↑ の記事には書いてある。その結果、 node_modules 内のパスで色々やる系のライブラリは色々と変更を迫られている。この記事もほぼ pnp 対応に費やされた。

大胆な変更だが、 npm 側にも tink というプロジェクトがあり、ほぼ同じような設計なので、npm でも似たような変更が予定されていた。ので、これ自体は yarn が勝手にやってるという感じでもない。

https://github.com/npm/tink

初期化

mkdir newprj
cd newprj
yarn set berry
yarn init

typescript + pnpify

vscode はデフォルトでは node_modules/@types/ の型を探索してしまうため、型定義ファイルが見つからない。これを pnpify で解決する。

yarn add @yarnpkg/pnpify
yarn pnpify --sdk # .vscode を書き換えられるので、コミットする必要がある

vscode で ts 拡張子のファイルを開き、右下の TypeScript のバージョン選択から、  Use workspace version: 3.7.5-pnpify を選択

これで VSCode 内で実行可能になった。

参考: https://yarnpkg.com/advanced/editor-sdks

jest

jest-pnp-resolver を使う

yarn add jest-pnp-resolver -D

module.exports = {
  resolver: require.resolve("jest-pnp-resolver"),
  transform: {
    "^.+\\.tsx?$": "ts-jest"
  },
  testRegex: "(/__tests__/.*)\\.test\\.tsx?$",
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node", "wasm"]
};

pnp + webpack

pnp-webpack-plugin を使えば webpack も使える。

// webpack.config.js
const path = require("path");
const PnpWebpackPlugin = require(`pnp-webpack-plugin`);
module.exports = {
  resolve: {
    extensions: [".js", "json", ".ts", ".tsx", ".wasm"],
    plugins: [PnpWebpackPlugin]
  },
  resolveLoader: {
    plugins: [PnpWebpackPlugin.moduleLoader(module)]
  },
  entry: {
    main: path.join(__dirname, "packages/webapp/src/index")
  },
  output: {
    filename: "[name].js",
    path: path.join(__dirname, "dist")
  },
  module: {
    rules: [
      {
        test: /\.tsx?/,
        use: [
          {
            loader: "ts-loader",
            options: {
              transpileOnly: true
            }
          }
        ]
      }
    ]
  }
};

しかし一つ問題が発生した。packages/webapp を掘って、その下で yarn add webpack webpack-cli -D を行ったが、このディレクトリからの yarn webpack 実行時には webpack-cli が見つからず、 webpack の実行ができなかった。

おとなしくルートディレクトリにインストールした。

.gitignore

ゼロインストールが目玉機能だが、普通のプロジェクトでやると git object が現実的なサイズに収まる気がしないので、とりあえずゼロインストールじゃない版の .gitignore を採用

https://github.com/yarnpkg/berry/issues/454#issuecomment-530312089

.yarn/*
!.yarn/releases
!.yarn/plugins
.pnp.*
dist
node_modules

node_modules は発生しない…はずなのだが、webpack を使うと terser-webpack-pluginnode_modules/.cache を生成していた。これは単に無視していいと思う

workspaces

これに関しては yarn v1 よりはるかに素晴らしい。yarn v1 の workspaces はどの位置で yarn install を発行したかで頻繁に整合性が崩れていたが、 node_modules が生えずにルートディレクトリの.yarn/cache にちゃんとエイリアスが集約された。

packages/
  foo
  bar
  nested/
    nested-a
    package.json # "workspaces": ["packages/*"]
package.json # "workspaces": ["packages/*"]

この状態で foo から nested-a が import できた。(もとからできていたが、挙動が怪しかった)

ライブラリ作者の考えること

相対パスから node_modules を探索する系の処理を自前で書いてしまうと、基本的に berry では動かなくなる。

いつ使うか

現状、手数が多すぎる。それもほとんどが pnp 周りで発生したもので、エコシステムがどれぐらい yarn v2 に配慮するか、というところに、使い物になるかの分岐点がありそう。yarn v2 側が折れて node_modules のフォールバックをすることも考えられうる。

余談だが、 npm 社は経営不安で大規模なレイオフを敢行するなどしており、tink は開発が止まっている。もはや npm tink を実装するエンジニアリソースがないのではないかと、個人的に疑っている。github package registry の一般公開も済んだので、個人的には npm 社のインフラやリソースに依存したくない気持ちがある。npm/npm の issue も放置されがち。

経営不安な運営元のソフトウェアは、例えばこういうことが起きるので…

Opera Softwareが最大876%の暴利ローンアプリで不正に荒稼ぎしてたことが判明、摘発されればOperaブラウザ終了の可能性も - GIGAZINE

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした