Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SyntaxError: The requested module '@reduxjs/toolkit' does not provide an export named 'createSlice' from inside Jest test #3864

Closed
ChristophP opened this issue Nov 10, 2023 · 2 comments

Comments

@ChristophP
Copy link

ChristophP commented Nov 10, 2023

Problem

Currently redux toolkit causes errors when using named exports in ESM modules from within Node (when using Jest)

An example:
There is a source code file like this in my Frontend code, which gets bundled a bundler (Parcel in this case, Vite, Webpack etc would be similar).

// some-slice.js
import { createSlice } from '@reduxjs/toolkit';

// define the slice.

Then I have a test which tests things in this file. The test is run via Jest through a modern version of Node (18 in this case).

import { stuff } from './some-slice';

// run the test

This results in the following error when Jest is run.

SyntaxError: The requested module '@reduxjs/toolkit' does not provide an export named 'createSlice.

The package.json contains type: module and the jest tests are run with NODE_OPTIONS=--experimental-vm-modules jest src (which is currently needed to run Jest with ESM enabled)

Easy way to reproduce

mkdir test
cd test
echo '{"type": "module"}' > package.json
npm init -y
echo 'import { createSlice } from "@reduxjs/toolkit"' > index.mjs # note the .mjs extension to force ESM (type module in package.json also works)
node index.mjs #throws the error

Why does this happen?

Short answer

Redux toolkit's ESM module definition is broken for named exports, when using native ESM in NodeJS.

Long answer

Redux toolkit's package.json currently exposes two entrypoints in the package json.

  "main": "dist/index.js",
  "module": "dist/redux-toolkit.esm.js",

main is used for NodeJS CJS code.
module provides an ESM export. However, this field is only used by bundlers and ignored by NodeJS.

This means that when using CJS node chooses the main field to require() the redux toolkit code.
But when Node is running ESM it does NOT use the module field because Node does not support this field, falling back to importing the CJS file specified in main (which is possible because of the backward compatibilty provided by Node).

However, this backward compatibility comes at a cost. Namely the fact that named exports don't work properly. NodeJs tries to provide named exports for CJS code imported by ESM code using a runtime check but the fact is that only the default export is reliable because CJS exports are not wenn suited for static analysis. Using the default export is not possible however, when using a bundler because the ESM version of the code provided by the "module" field, has no default export, only named exports. So one is "stuck", there's no way to satisfy the two at the moment.

Proposed Solution

NodeJS does not support the module field but it does support the exports field. Adding something like this to the package.json would allow NodeJS to import the correct ESM/CJS variant of the build

{
  "main": "dist/index.js",
  "module": "dist/redux-toolkit.esm.js",
  "unpkg": "dist/redux-toolkit.umd.min.js",
  "types": "dist/index.d.ts",
  "exports" {
    "types": "dist/index.d.ts",
    "import": "dist/redux-toolkit.mjs", // note that this must have an .mjs extension (or type: "module" in the package.json) to be interpreted as ESM 
   "require": "dist/index.js"
  }
}

This would solve the problem for Node and allow importing of the ESM build. Note that the file must have an .mjs extension since type: module is currently not set in the package.json.

Using this might even make the module field obsolete since bundlers tend to prefer exports if it's provided over module, but it doesn't hurt to leave it there.

@EskiMojo14
Copy link
Collaborator

EskiMojo14 commented Nov 10, 2023

see #3849 - this is fixed in the 2.0 betas.

@ChristophP
Copy link
Author

Great to know. Thx 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants