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-plugin
が node_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