現象
以下の構成でstorybookがエラーで動かない
- Next.js
- Storybook
- yarn v3
- Plug'n'Play
対処法
.yarnrc.ymlに以下を追記します。
packageExtensions:
"@storybook/nextjs@*":
dependencies:
"@babel/core": "*"
webpack: "*"
以下のコマンドを実行します。
corepack yarn add -D styled-jsx postcss-import postcss-loader css-loader postcss-url
考察
yarn v3のPlug'n'Playではnode_modulesが廃止になり、依存パッケージは.yarn/cacheに格納されるようになりました。パッケージをimportしたとき、yarnがModule._loadをオーバーライドすることで依存関係の解決を行っているようです。1
.yarnrc.ymlにnodeLinker: node-modulesを記述しPlug'n'Playを無効化した場合、storybookは問題なく機能します。
これらのことから、yarnによりオーバーライドされたModule._loadは、パッケージのpeerDependenciesをimportできないようになっていると考えられます。2
❯ corepack yarn sb
@storybook/cli v7.0.27
WARN Failed to load preset: "@storybook\\nextjs\\preset"
ERR! Error: @storybook/nextjs tried to access webpack (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound.
ERR!
ERR! Required package: webpack
ERR! Required by: @storybook/nextjs@virtual:...
:
この場合は@storybook/nextjsが自身のpeerDependenciesであるwebpackにアクセスできないので、@storybook/nextjsのdependenciesにwebpackを指定すれば動作します。
Plug'n'Playではパッケージがzipファイルに格納されていて、package.jsonを直接編集できません。yarn patchを使えば可能ですが、今回は.yarnrc.ymlのpackageExtensionsを使用し、パッケージの依存関係を拡張することで解決しました。
今回のように、Error: [パッケージ名] tried to access [依存パッケージ名] (a peer dependency) but it isn't provided by ...のようなエラーが発生する場合、packageExtensionsを用いた解決法が有効である場合が多いです。
参考
-
出典が見つからなかったため、「別の問題があり、今回の対処法が偶然機能した」などの可能性があります。 ↩