LoginSignup
121
45

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-02-18

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 とは

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

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

初期化

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 を採用

.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

121
45
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
121
45