diff --git a/packages/toolkit/jest.config.js b/packages/toolkit/jest.config.js index 16cc49cf96..b332f3a10d 100644 --- a/packages/toolkit/jest.config.js +++ b/packages/toolkit/jest.config.js @@ -1,4 +1,4 @@ -module.exports = { +export default { testEnvironment: 'jest-environment-jsdom', setupFilesAfterEnv: ['./jest.setup.js'], testMatch: ['/src/**/*.(spec|test).[jt]s?(x)'], diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index fa3977216b..003ebf295c 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -22,10 +22,28 @@ "publishConfig": { "access": "public" }, - "main": "dist/index.js", + "type": "module", "module": "dist/redux-toolkit.modern.js", - "unpkg": "dist/redux-toolkit.umd.min.js", + "main": "dist/cjs/index.js", "types": "dist/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/redux-toolkit.modern.js", + "default": "./dist/cjs/index.js" + }, + "./query": { + "types": "./dist/query/index.d.ts", + "import": "./dist/query/rtk-query.modern.js", + "default": "./dist/query/cjs/index.js" + }, + "./query/react": { + "types": "./dist/query/react/index.d.ts", + "import": "./dist/query/react/rtk-query-react.modern.js", + "default": "./dist/query/react/cjs/index.js" + } + }, "devDependencies": { "@microsoft/api-extractor": "^7.13.2", "@size-limit/preset-small-lib": "^4.11.0", @@ -101,7 +119,7 @@ "dependencies": { "immer": "^9.0.16", "redux": "^4.2.0", - "redux-thunk": "^2.4.2", + "redux-thunk": "3.0.0-alpha.1", "reselect": "^4.1.7" }, "peerDependencies": { diff --git a/packages/toolkit/query/package.json b/packages/toolkit/query/package.json index f093468b90..ca99300e54 100644 --- a/packages/toolkit/query/package.json +++ b/packages/toolkit/query/package.json @@ -2,10 +2,18 @@ "name": "@reduxjs/toolkit-query", "version": "1.0.0", "description": "", - "main": "../dist/query/index.js", + "type": "module", "module": "../dist/query/rtk-query.modern.js", - "unpkg": "../dist/query/rtk-query.umd.min.js", - "types": "../dist/query/index.d.ts", + "main": "../dist/query/cjs/index.js", + "types": "./../dist/query/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./../dist/query/index.d.ts", + "import": "./../dist/query/rtk-query.modern.js", + "default": "./../dist/query/cjs/index.js" + } + }, "author": "Mark Erikson ", "license": "MIT", "sideEffects": false diff --git a/packages/toolkit/query/react/package.json b/packages/toolkit/query/react/package.json index 69f96cec3b..20fcabea62 100644 --- a/packages/toolkit/query/react/package.json +++ b/packages/toolkit/query/react/package.json @@ -2,11 +2,19 @@ "name": "@reduxjs/toolkit-query-react", "version": "1.0.0", "description": "", - "main": "../../dist/query/react/index.js", + "type": "module", "module": "../../dist/query/react/rtk-query-react.modern.js", - "unpkg": "../../dist/query/react/rtk-query-react.umd.min.js", + "main": "../../dist/query/react/cjs/index.js", + "types": "./../../dist/query/react/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./../../dist/query/react/index.d.ts", + "import": "./../../dist/query/react/rtk-query-react.modern.js", + "default": "./../../dist/query/react/cjs/index.js" + } + }, "author": "Mark Erikson ", "license": "MIT", - "types": "../../dist/query/react/index.d.ts", "sideEffects": false } diff --git a/packages/toolkit/scripts/build.ts b/packages/toolkit/scripts/build.ts index 4521752b93..b66f456ed0 100644 --- a/packages/toolkit/scripts/build.ts +++ b/packages/toolkit/scripts/build.ts @@ -1,7 +1,9 @@ /* eslint-disable import/first */ +import { fileURLToPath } from 'url' + // @ts-check import { build } from 'esbuild' -import terser from 'terser' +import { minify as terserMinify } from 'terser' import { rollup } from 'rollup' import path from 'path' import fs from 'fs-extra' @@ -16,7 +18,9 @@ import { extractInlineSourcemap, removeInlineSourceMap } from './sourcemap' import type { BuildOptions, EntryPointOptions } from './types' import { appendInlineSourceMap, getLocation } from './sourcemap' -const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) +// No __dirname under Node ESM +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) const { argv } = yargs(process.argv) .option('local', { @@ -36,14 +40,14 @@ const buildTargets: BuildOptions[] = [ { format: 'cjs', name: 'cjs.development', - target: 'es2018', + target: 'esnext', minify: false, env: 'development', }, { format: 'cjs', name: 'cjs.production.min', - target: 'es2018', + target: 'esnext', minify: true, env: 'production', }, @@ -51,7 +55,7 @@ const buildTargets: BuildOptions[] = [ { format: 'esm', name: 'modern', - target: 'es2018', + target: 'esnext', minify: false, env: '', }, @@ -59,7 +63,7 @@ const buildTargets: BuildOptions[] = [ { format: 'esm', name: 'modern.development', - target: 'es2018', + target: 'esnext', minify: false, env: 'development', }, @@ -67,24 +71,24 @@ const buildTargets: BuildOptions[] = [ { format: 'esm', name: 'modern.production.min', - target: 'es2018', - minify: true, - env: 'production', - }, - { - format: 'umd', - name: 'umd', - target: 'es2018', - minify: false, - env: 'development', - }, - { - format: 'umd', - name: 'umd.min', - target: 'es2018', + target: 'esnext', minify: true, env: 'production', }, + // { + // format: 'umd', + // name: 'umd', + // target: 'es2018', + // minify: false, + // env: 'development', + // }, + // { + // format: 'umd', + // name: 'umd.min', + // target: 'es2018', + // minify: true, + // env: 'production', + // }, ] const entryPoints: EntryPointOptions[] = [ @@ -118,6 +122,9 @@ const esVersionMappings = { es2018: ts.ScriptTarget.ES2018, es2019: ts.ScriptTarget.ES2019, es2020: ts.ScriptTarget.ES2020, + es2021: ts.ScriptTarget.ES2021, + es2022: ts.ScriptTarget.ES2022, + esnext: ts.ScriptTarget.ESNext, } async function bundle(options: BuildOptions & EntryPointOptions) { @@ -132,10 +139,23 @@ async function bundle(options: BuildOptions & EntryPointOptions) { entryPoint, } = options - const outputFolder = path.join('dist', folder) + const folderSegments = [outputDir, folder] + + if (format === 'cjs') { + folderSegments.push('cjs') + } + + const outputFolder = path.join(...folderSegments) const outputFilename = `${prefix}.${name}.js` + + await fs.ensureDir(outputFolder) + const outputFilePath = path.join(outputFolder, outputFilename) + if (format === 'cjs') { + await writeCommonJSEntry(outputFolder, prefix) + } + const result = await build({ entryPoints: [entryPoint], outfile: outputFilePath, @@ -212,7 +232,7 @@ async function bundle(options: BuildOptions & EntryPointOptions) { let mapping: RawSourceMap = mergedSourcemap if (minify) { - const transformResult = await terser.minify( + const transformResult = await terserMinify( appendInlineSourceMap(code, mapping), { sourceMap: { @@ -237,12 +257,14 @@ async function bundle(options: BuildOptions & EntryPointOptions) { } const relativePath = path.relative(process.cwd(), chunk.path) - console.log(`Build artifact: ${relativePath}, settings: `, { - target, - output: ts.ScriptTarget[esVersion], - }) await fs.writeFile(chunk.path, code) await fs.writeJSON(chunk.path + '.map', mapping) + + if (!chunk.path.includes('.map')) { + console.log(`Build artifact: ${relativePath}, settings: `, { + target, + }) + } } } @@ -279,9 +301,9 @@ async function buildUMD( } // Generates an index file to handle importing CJS dev/prod -async function writeEntry(folder: string, prefix: string) { +async function writeCommonJSEntry(folder: string, prefix: string) { await fs.writeFile( - path.join('dist', folder, 'index.js'), + path.join(folder, 'index.js'), `'use strict' if (process.env.NODE_ENV === 'production') { module.exports = require('./${prefix}.cjs.production.min.js') @@ -289,6 +311,8 @@ if (process.env.NODE_ENV === 'production') { module.exports = require('./${prefix}.cjs.development.js') }` ) + + await fs.writeFile(path.join(folder, 'package.json'), `{"type": "commonjs"}`) } interface BuildArgs { @@ -313,14 +337,13 @@ async function main({ skipExtraction = false, local = false }: BuildArgs) { }) ) await Promise.all(bundlePromises) - await writeEntry(folder, prefix) } // Run UMD builds after everything else so we don't have to sleep after each set for (let entryPoint of entryPoints) { const { folder } = entryPoint const outputPath = path.join('dist', folder) - await buildUMD(outputPath, entryPoint.prefix, entryPoint.globalName) + // await buildUMD(outputPath, entryPoint.prefix, entryPoint.globalName) } if (!skipExtraction) { diff --git a/packages/toolkit/scripts/types.ts b/packages/toolkit/scripts/types.ts index cf0d8f889c..9a9f48e626 100644 --- a/packages/toolkit/scripts/types.ts +++ b/packages/toolkit/scripts/types.ts @@ -11,7 +11,14 @@ export interface BuildOptions { | 'umd.min' minify: boolean env: 'development' | 'production' | '' - target?: 'es2017' | 'es2018' | 'es2019' | 'es2020' + target?: + | 'es2017' + | 'es2018' + | 'es2019' + | 'es2020' + | 'es2021' + | 'es2022' + | 'esnext' } export interface EntryPointOptions { diff --git a/packages/toolkit/src/configureStore.ts b/packages/toolkit/src/configureStore.ts index aae2307c9d..76f5a0519c 100644 --- a/packages/toolkit/src/configureStore.ts +++ b/packages/toolkit/src/configureStore.ts @@ -34,7 +34,7 @@ const IS_PRODUCTION = process.env.NODE_ENV === 'production' * @public */ export type ConfigureEnhancersCallback = ( - defaultEnhancers: readonly StoreEnhancer[] + defaultEnhancers: readonly StoreEnhancer[] ) => [...E] /** @@ -107,7 +107,7 @@ type Enhancers = ReadonlyArray export interface ToolkitStore< S = any, A extends Action = AnyAction, - M extends Middlewares = Middlewares, + M extends Middlewares = Middlewares > extends Store { /** * The `dispatch` method of your store, enhanced by all its middlewares. diff --git a/packages/toolkit/src/createReducer.ts b/packages/toolkit/src/createReducer.ts index dd749f398e..e22b0a007a 100644 --- a/packages/toolkit/src/createReducer.ts +++ b/packages/toolkit/src/createReducer.ts @@ -1,5 +1,5 @@ import type { Draft } from 'immer' -import createNextState, { isDraft, isDraftable } from 'immer' +import { produce as createNextState, isDraft, isDraftable } from 'immer' import type { AnyAction, Action, Reducer } from 'redux' import type { ActionReducerMapBuilder } from './mapBuilders' import { executeReducerBuilderCallback } from './mapBuilders' diff --git a/packages/toolkit/src/entities/state_adapter.ts b/packages/toolkit/src/entities/state_adapter.ts index fbc1577683..220abae40a 100644 --- a/packages/toolkit/src/entities/state_adapter.ts +++ b/packages/toolkit/src/entities/state_adapter.ts @@ -1,4 +1,4 @@ -import createNextState, { isDraft } from 'immer' +import { produce as createNextState, isDraft } from 'immer' import type { EntityState, PreventAny } from './models' import type { PayloadAction } from '../createAction' import { isFSA } from '../createAction' diff --git a/packages/toolkit/src/getDefaultMiddleware.ts b/packages/toolkit/src/getDefaultMiddleware.ts index e54a667680..655b0dc931 100644 --- a/packages/toolkit/src/getDefaultMiddleware.ts +++ b/packages/toolkit/src/getDefaultMiddleware.ts @@ -1,6 +1,6 @@ import type { Middleware, AnyAction } from 'redux' import type { ThunkMiddleware } from 'redux-thunk' -import thunkMiddleware from 'redux-thunk' +import { thunk as thunkMiddleware, withExtraArgument } from 'redux-thunk' import type { ImmutableStateInvariantMiddlewareOptions } from './immutableStateInvariantMiddleware' /* PROD_START_REMOVE_UMD */ import { createImmutableStateInvariantMiddleware } from './immutableStateInvariantMiddleware' @@ -88,9 +88,7 @@ export function getDefaultMiddleware< if (isBoolean(thunk)) { middlewareArray.push(thunkMiddleware) } else { - middlewareArray.push( - thunkMiddleware.withExtraArgument(thunk.extraArgument) - ) + middlewareArray.push(withExtraArgument(thunk.extraArgument)) } } diff --git a/packages/toolkit/src/tests/configureStore.typetest.ts b/packages/toolkit/src/tests/configureStore.typetest.ts index 1fc5432bd6..76bbfc8ac8 100644 --- a/packages/toolkit/src/tests/configureStore.typetest.ts +++ b/packages/toolkit/src/tests/configureStore.typetest.ts @@ -6,7 +6,7 @@ import type { Reducer, Store, Action, - StoreEnhancer + StoreEnhancer, } from 'redux' import { applyMiddleware } from 'redux' import type { PayloadAction } from '@reduxjs/toolkit' @@ -17,7 +17,7 @@ import { ConfigureStoreOptions, } from '@reduxjs/toolkit' import type { ThunkMiddleware, ThunkAction, ThunkDispatch } from 'redux-thunk' -import thunk from 'redux-thunk' +import { thunk } from 'redux-thunk' import { expectNotAny, expectType } from './helpers' const _anyMiddleware: any = () => () => () => {} @@ -144,10 +144,12 @@ const _anyMiddleware: any = () => () => () => {} { const store = configureStore({ reducer: () => 0, - enhancers: [applyMiddleware(() => next => next)] + enhancers: [applyMiddleware(() => (next) => next)], }) - expectType>(store.dispatch) + expectType>( + store.dispatch + ) } configureStore({ @@ -159,7 +161,7 @@ const _anyMiddleware: any = () => () => () => {} { type SomePropertyStoreEnhancer = StoreEnhancer<{ someProperty: string }> - const somePropertyStoreEnhancer: SomePropertyStoreEnhancer = next => { + const somePropertyStoreEnhancer: SomePropertyStoreEnhancer = (next) => { return (reducer, preloadedState) => { return { ...next(reducer, preloadedState), @@ -168,9 +170,13 @@ const _anyMiddleware: any = () => () => () => {} } } - type AnotherPropertyStoreEnhancer = StoreEnhancer<{ anotherProperty: number }> + type AnotherPropertyStoreEnhancer = StoreEnhancer<{ + anotherProperty: number + }> - const anotherPropertyStoreEnhancer: AnotherPropertyStoreEnhancer = next => { + const anotherPropertyStoreEnhancer: AnotherPropertyStoreEnhancer = ( + next + ) => { return (reducer, preloadedState) => { return { ...next(reducer, preloadedState), @@ -184,7 +190,9 @@ const _anyMiddleware: any = () => () => () => {} enhancers: [somePropertyStoreEnhancer, anotherPropertyStoreEnhancer], }) - expectType>(store.dispatch) + expectType>( + store.dispatch + ) expectType(store.someProperty) expectType(store.anotherProperty) } @@ -348,7 +356,9 @@ const _anyMiddleware: any = () => () => () => {} { const store = configureStore({ reducer: reducerA, - middleware: [] as any as readonly [Middleware<(a: StateA) => boolean, StateA>], + middleware: [] as any as readonly [ + Middleware<(a: StateA) => boolean, StateA> + ], }) const result: boolean = store.dispatch(5) // @ts-expect-error @@ -532,21 +542,23 @@ const _anyMiddleware: any = () => () => () => {} initialState: null as any, reducers: { set(state) { - return state; + return state }, }, - }); + }) - function configureMyStore(options: Omit, 'reducer'>) { + function configureMyStore( + options: Omit, 'reducer'> + ) { return configureStore({ ...options, reducer: someSlice.reducer, - }); + }) } - const store = configureMyStore({}); + const store = configureMyStore({}) - expectType(store.dispatch); + expectType(store.dispatch) } { diff --git a/packages/toolkit/src/tests/getDefaultMiddleware.test.ts b/packages/toolkit/src/tests/getDefaultMiddleware.test.ts index 2367ae4040..c47e3905cc 100644 --- a/packages/toolkit/src/tests/getDefaultMiddleware.test.ts +++ b/packages/toolkit/src/tests/getDefaultMiddleware.test.ts @@ -11,7 +11,7 @@ import { MiddlewareArray, configureStore, } from '@reduxjs/toolkit' -import thunk from 'redux-thunk' +import { thunk } from 'redux-thunk' import type { ThunkMiddleware } from 'redux-thunk' import { expectType } from './helpers' @@ -23,10 +23,20 @@ describe('getDefaultMiddleware', () => { process.env.NODE_ENV = ORIGINAL_NODE_ENV }) - it('returns an array with only redux-thunk in production', () => { - process.env.NODE_ENV = 'production' + describe('Production behavior', () => { + beforeEach(() => { + jest.resetModules() + }) + + it('returns an array with only redux-thunk in production', () => { + process.env.NODE_ENV = 'production' + const { thunk } = require('redux-thunk') + const { getDefaultMiddleware } = require('@reduxjs/toolkit') - expect(getDefaultMiddleware()).toEqual([thunk]) // @remap-prod-remove-line + const middleware = getDefaultMiddleware() + expect(middleware).toContain(thunk) + expect(middleware.length).toBe(1) + }) }) it('returns an array with additional middleware in development', () => { diff --git a/packages/toolkit/src/utils.ts b/packages/toolkit/src/utils.ts index 40957c2788..9697d31bb6 100644 --- a/packages/toolkit/src/utils.ts +++ b/packages/toolkit/src/utils.ts @@ -1,4 +1,4 @@ -import createNextState, { isDraftable } from 'immer' +import { produce as createNextState, isDraftable } from 'immer' import type { Middleware } from 'redux' export function getTimeMeasureUtils(maxDelay: number, fnName: string) { diff --git a/yarn.lock b/yarn.lock index 816ef37411..68b2f0be9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6596,7 +6596,7 @@ __metadata: prettier: ^2.2.1 query-string: ^7.0.1 redux: ^4.2.0 - redux-thunk: ^2.4.2 + redux-thunk: 3.0.0-alpha.1 reselect: ^4.1.7 rimraf: ^3.0.2 rollup: ^2.47.0 @@ -23551,6 +23551,15 @@ fsevents@^1.2.7: languageName: node linkType: hard +"redux-thunk@npm:3.0.0-alpha.1": + version: 3.0.0-alpha.1 + resolution: "redux-thunk@npm:3.0.0-alpha.1" + peerDependencies: + redux: ^4 + checksum: 280e0d399c96d071030f6dfa5bdb0b05b9f228dd0b840ffbb213e778b773efc25e6ba24f7ed13818696ea54a359ecc06a9e5e718e07d960a772101b14c0dd8c7 + languageName: node + linkType: hard + "redux-thunk@npm:^2.4.1": version: 2.4.1 resolution: "redux-thunk@npm:2.4.1"