redux-toolkit: rtk query imports fail with pnpm package manager and snowpack

I’m trying to use rtk query in a project with snowpack and react, using pnpm to install the package. When I add the following import statement: import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; And then run the dev server, I get the error: [12:19:17] [snowpack] Error: Package "immer" not found. Have you installed it? [12:19:17] [snowpack] [500] /_snowpack/pkg/@reduxjs/toolkit.v1.8.0/common/redux-toolkit.esm-c546b9d2.js

It appears that pnpm is not able to figure out that immer, redux-thunk, and reselect are dependencies for rtk as well as rtk query. After looking into the problem for a while, I think the issue is that rtk query and rtk query react are organized as separate repos inside of a monorepo, but the file structure is not understood by pnpm. based on these docs: https://pnpm.io/workspaces I think that the problem could be resolved by adding a pnpm-workspace.yaml file with something like this (not tested):

packages:
  - 'query/react/*'
  - 'query/*'
  - '*'

As a temporary workaround, I manually installed immer, redux-thunk, and reselect as dependencies, and after that the dev server started without errors. I think I’ve added enough details to reproduce the issue but please let me know if you want a minimal example repo. Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 21 (7 by maintainers)

Most upvoted comments

Some additional info that might come helpful for Snowpack maintainers…

This already happens when we have a source code like this:

import '@reduxjs/toolkit';
import '@reduxjs/toolkit/query';

Where @reduxjs/toolkit resolves to a file specified by @reduxjs/toolkit/package.json#module and where that file can be simplified to:

import { enableES5 } from "immer";
enableES5();
export {};

And where @reduxjs/toolkit/query resolves to a file specified by @reduxjs/toolkit/query/package.json#main (note that this is not correct! it should resolve to #module, but that’s a separate issue) and where that file can be simplified to:

import * as T from "@reduxjs/toolkit" // I've also tried to use a relative path here, but with no success
import * as I from "immer"
console.log({ T, I })

The problem seems to be in some core logic of Snowpack. In its internals we can observe that this can’t be resolved properly: https://github.com/withastro/snowpack/blob/f2252506b2fc7acdd46778103a262337d396332c/esinstall/src/entrypoints.ts#L157

There are 3 requests for immer there - one is related to immer itself so let’s ignore it. Another one looks like this and is successful:

{
  "dep": "immer",
  "cwd": "~/rtk-query-pnpm-import-bug/node_modules/.pnpm/@reduxjs+toolkit@1.8.0_react-redux@7.2.6+react@17.0.2/node_modules/@reduxjs/toolkit/dist/redux-toolkit.esm.js"
}

whereas the one that fails looks like this:

{
  "dep": "immer",
  "cwd": "~/rtk-query-pnpm-import-bug/node_modules/.cache/snowpack/build/@reduxjs/toolkit@1.8.0/package.json"
}

We can notice here that the second one happens from within the .cache/snowpack directory and thus the proper manifest (aka package.json) can’t be found.

The request itself goes through this: https://github.com/withastro/snowpack/blob/f2252506b2fc7acdd46778103a262337d396332c/snowpack/src/sources/local.ts#L278

where:

{
  "id": "@reduxjs/toolkit.v1.8.0/common/redux-toolkit.esm-eaab66fb.js"
}

So this comes from an already preprocessed file, one for which the entrypoint (later used as cwd) is already set here as:

{
  "entrypoint": "~/rtk-query-pnpm-import-bug/node_modules/.cache/snowpack/build/@reduxjs/toolkit@1.8.0/package.json"
}

One could compare what happens when npm/yarn are used - but my guess would be that this “request” comes from within node_modules and not from the cache directory. So the problem is most likely at some earlier step that I’ve been investigating.

Oh, I might have misunderstood the issue at hand in a rush. Gonna clone that repo in a moment and take a closer look.

@phryneas feel free to ping me any time 😃

You can’t add dependencies to “subentries” - those nested package.json just allow you to “route” requests to specific files (through pkg.json#main/module etc) when using the classic node.js require algorithm. They don’t have any effect on what dependencies are installed etc

The problem in here is that pnpm is a “strict package manager” (the same would happen with yarn’s PnP). You need to declare all of your dependencies explicitly and you can’t rely on node_modules hoisting and similar mechanisms. You basically have 3 choices:

  • publish separate packages that would integrate with specific libraries, that way each one could have isolated dependencies
  • add everything to dependencies
  • declare optional peer dependencies