Skip to content

Commit 9e7e6f6

Browse files
committed
Merge branch 'master' of https://github.com/reduxjs/redux-toolkit into improve-treeshakeability
2 parents ee51d76 + e33130e commit 9e7e6f6

File tree

127 files changed

+6710
-1585
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+6710
-1585
lines changed

.github/workflows/tests.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,60 @@ jobs:
9999
TEST_DIST: true
100100
run: yarn test
101101

102+
- name: Run type tests with `moduleResolution Bundler`
103+
run: rm -rf dist && yarn tsc -p . --moduleResolution Bundler --module ESNext --noEmit false --declaration --emitDeclarationOnly --outDir dist --target ESNext && rm -rf dist
104+
105+
test-type-portability:
106+
name: Test Type Portability with TypeScript ${{ matrix.ts }} and Node.js ${{ matrix.node }}
107+
needs: [build]
108+
runs-on: ubuntu-latest
109+
strategy:
110+
fail-fast: false
111+
matrix:
112+
node: ['20.x']
113+
ts: ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', 'next']
114+
example:
115+
[
116+
{ name: 'bundler', moduleResolution: 'Bundler' },
117+
{ name: 'nodenext-cjs', moduleResolution: 'NodeNext' },
118+
{ name: 'nodenext-esm', moduleResolution: 'NodeNext' },
119+
]
120+
steps:
121+
- name: Checkout repo
122+
uses: actions/checkout@v4
123+
124+
- name: Use node ${{ matrix.node }}
125+
uses: actions/setup-node@v4
126+
with:
127+
node-version: ${{ matrix.node }}
128+
cache: 'yarn'
129+
130+
- name: Install deps
131+
run: yarn install
132+
133+
- uses: actions/download-artifact@v4
134+
with:
135+
name: package
136+
path: packages/toolkit
137+
138+
- name: Install build artifact
139+
run: yarn workspace @examples-type-portability/${{ matrix.example.name }} add $(pwd)/package.tgz
140+
141+
- name: Install TypeScript ${{ matrix.ts }}
142+
run: yarn workspace @examples-type-portability/${{ matrix.example.name }} add -D typescript@${{ matrix.ts }}
143+
144+
- name: Test type portability with `moduleResolution ${{ matrix.example.moduleResolution }}`
145+
run: yarn workspace @examples-type-portability/${{ matrix.example.name }} run test
146+
147+
- name: Test type portability with `moduleResolution Node10`
148+
run: yarn workspace @examples-type-portability/${{ matrix.example.name }} run test --module CommonJS --moduleResolution Node10 --preserveSymLinks --verbatimModuleSyntax false
149+
150+
- name: Test type portability with `moduleResolution Node10` and `type module` in `package.json`
151+
if: matrix.example.name == 'nodenext-esm' || matrix.example.name == 'bundler'
152+
run: |
153+
npm --workspace=@examples-type-portability/${{ matrix.example.name }} pkg set type=module
154+
yarn workspace @examples-type-portability/${{ matrix.example.name }} run test --module ESNext --moduleResolution Node10 --preserveSymLinks --verbatimModuleSyntax false
155+
102156
test-types:
103157
name: Test Types with TypeScript ${{ matrix.ts }}
104158

.yarn/patches/console-testing-library-npm-0.6.1-4d9957d402.patch

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
1+
diff --git a/package.json b/package.json
2+
index b924e066ecfdb30917b9c1056b360834da357698..15e155bd84f9d16537ffe36f9a87debcb0ec3591 100644
3+
--- a/package.json
4+
+++ b/package.json
5+
@@ -8,12 +8,15 @@
6+
"type": "module",
7+
"main": "dist/index.js",
8+
"typings": "index.d.ts",
9+
+ "types": "index.d.ts",
10+
"exports": {
11+
".": {
12+
+ "types": "./index.d.ts",
13+
"require": "./dist/index.js",
14+
"default": "./src/index.js"
15+
},
16+
"./pure": {
17+
+ "types": "./pure.d.ts",
18+
"require": "./dist/pure.js",
19+
"default": "./src/pure.js"
20+
}
21+
diff --git a/pure.d.ts b/pure.d.ts
22+
index b13bb4eb87d0b316bb51bd6094b2353c6fc8527d..ee01cc9bd3233f5e67b050d48e22202b495a4a0a 100644
23+
--- a/pure.d.ts
24+
+++ b/pure.d.ts
25+
@@ -1 +1 @@
26+
-export * from './';
27+
+export * from './index.js';
128
diff --git a/src/index.js b/src/index.js
229
index 90ff7fa3d7d4fa62dbbf638958ae4e28abd089a8..28434687b5163b7472e86bdb11bed69e0868e660 100644
330
--- a/src/index.js
431
+++ b/src/index.js
532
@@ -1,4 +1,4 @@
633
-import { mockConsole, createConsole } from './pure';
734
+import { mockConsole, createConsole } from './pure.js';
8-
35+
936
// Keep an instance of the original console and export it
1037
const originalConsole = global.console;
1138
diff --git a/src/pure.js b/src/pure.js
@@ -15,7 +42,7 @@ index b00ea2abbaea833e336676aa46e7ced2d59d6d88..42b83ed83fa16cf2234571500fe09868
1542
@@ -228,10 +228,11 @@ export function restore() {
1643
global.console = global.originalConsole;
1744
}
18-
45+
1946
+/*
2047
if (typeof expect === 'function' && typeof expect.extend === 'function') {
2148
expect.extend({
@@ -24,13 +51,13 @@ index b00ea2abbaea833e336676aa46e7ced2d59d6d88..42b83ed83fa16cf2234571500fe09868
2451
+ // Workaround for custom inline snapshot matchers
2552
const error = new Error();
2653
const stacks = error.stack.split('\n');
27-
54+
2855
@@ -245,7 +246,6 @@ if (typeof expect === 'function' && typeof expect.extend === 'function') {
2956
error.stack = stacks.join('\n');
30-
57+
3158
const context = Object.assign(this, { error });
3259
- /* -------------------------------------------------------------- */
33-
60+
3461
const testingConsoleInstance =
3562
(received && received.testingConsole) || received;
3663
@@ -270,3 +270,4 @@ if (typeof expect === 'function' && typeof expect.extend === 'function') {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@examples-type-portability/bundler",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "testing type portability for moduleResolution Bundler",
6+
"keywords": [],
7+
"main": "src/index.tsx",
8+
"dependencies": {
9+
"@reduxjs/toolkit": "workspace:^",
10+
"react": "^18.3.1",
11+
"react-dom": "^18.3.1",
12+
"react-redux": "^9.1.2",
13+
"react-router-dom": "^6.25.1",
14+
"react-scripts": "5.0.1"
15+
},
16+
"devDependencies": {
17+
"@types/node": "^20.14.11",
18+
"@types/react": "^18.3.3",
19+
"@types/react-dom": "^18.3.0",
20+
"typescript": "^5.5.4"
21+
},
22+
"eslintConfig": {
23+
"extends": [
24+
"react-app"
25+
],
26+
"rules": {
27+
"react/react-in-jsx-scope": "off"
28+
}
29+
},
30+
"scripts": {
31+
"clean": "rm -rf dist",
32+
"start": "react-scripts start",
33+
"build": "react-scripts build",
34+
"test": "yarn clean && tsc -p tsconfig.json"
35+
},
36+
"browserslist": [
37+
">0.2%",
38+
"not dead",
39+
"not ie <= 11",
40+
"not op_mini all"
41+
]
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Link, Route, Routes } from 'react-router-dom'
2+
import { Lazy } from './features/bundleSplitting'
3+
import { CounterList } from './features/counter/CounterList'
4+
import { PollingToggles } from './features/polling/PollingToggles'
5+
import { PostsManager } from './features/posts/PostsManager'
6+
import { TimeList } from './features/time/TimeList'
7+
8+
export function App() {
9+
return (
10+
<div className="App">
11+
<div className="row">
12+
<div className="column column1">
13+
<span>
14+
<Link to="/">Times</Link> | <Link to="/posts">Posts</Link> |{' '}
15+
<Link to="/counters">Counter</Link> |{' '}
16+
<Link to="/bundleSplitting">Bundle Splitting</Link>
17+
</span>
18+
</div>
19+
<div className="column column1">
20+
<PollingToggles />
21+
</div>
22+
</div>
23+
<div />
24+
<div>
25+
<Routes>
26+
<Route path="/" element={<TimeList />} />
27+
<Route path="/counters" element={<CounterList />} />
28+
<Route path="/posts/*" element={<PostsManager />} />
29+
<Route path="/bundleSplitting" element={<Lazy />} />
30+
</Routes>
31+
</div>
32+
</div>
33+
)
34+
}
35+
36+
export default App
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type {
2+
Api,
3+
BaseQueryFn,
4+
CoreModule,
5+
EndpointDefinitions,
6+
Module,
7+
} from '@reduxjs/toolkit/query'
8+
import { buildCreateApi, coreModule } from '@reduxjs/toolkit/query'
9+
10+
export const customModuleName = Symbol('customModule')
11+
export type CustomModule = typeof customModuleName
12+
13+
// If we remove this, We should get a TypeScript error.
14+
declare module '@reduxjs/toolkit/query' {
15+
export interface ApiModules<
16+
BaseQuery extends BaseQueryFn,
17+
Definitions extends EndpointDefinitions,
18+
ReducerPath extends string,
19+
TagTypes extends string,
20+
> {
21+
[customModuleName]: {
22+
endpoints: {
23+
[K in keyof Definitions]: {
24+
myEndpointProperty: string
25+
}
26+
}
27+
}
28+
}
29+
}
30+
31+
export const myModule = (): Module<CustomModule> => ({
32+
name: customModuleName,
33+
init(api, options, context) {
34+
// initialize stuff here if you need to
35+
36+
return {
37+
injectEndpoint(endpoint, definition) {
38+
const anyApi = api as any as Api<
39+
any,
40+
Record<string, any>,
41+
string,
42+
string,
43+
CustomModule | CoreModule
44+
>
45+
anyApi.endpoints[endpoint].myEndpointProperty = 'test'
46+
},
47+
}
48+
},
49+
})
50+
51+
export const myCreateApi = buildCreateApi(coreModule(), myModule())
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { createDynamicMiddleware } from '@reduxjs/toolkit'
2+
3+
export const dynamicMiddleware = createDynamicMiddleware()
4+
5+
export const { addMiddleware, instanceId, middleware, withMiddleware } =
6+
dynamicMiddleware
7+
8+
export const { withTypes, match, type } = withMiddleware
9+
10+
export const { withTypes: _withTypes } = addMiddleware
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { createDynamicMiddleware } from '@reduxjs/toolkit/react'
2+
import { listenerMiddleware } from './listenerMiddleware'
3+
4+
export const dynamicReactMiddleware = createDynamicMiddleware()
5+
6+
export const {
7+
addMiddleware,
8+
createDispatchWithMiddlewareHook,
9+
createDispatchWithMiddlewareHookFactory,
10+
instanceId,
11+
middleware,
12+
withMiddleware,
13+
} = dynamicReactMiddleware
14+
15+
export const { withTypes } = addMiddleware
16+
17+
export const useDispatchWithMiddleware = createDispatchWithMiddlewareHook(
18+
listenerMiddleware.middleware,
19+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useDispatch, useSelector, useStore } from 'react-redux'
2+
import type { AppDispatch, AppStore, RootState } from './store'
3+
4+
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
5+
export const useAppSelector = useSelector.withTypes<RootState>()
6+
export const useAppStore = useStore.withTypes<AppStore>()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { createListenerMiddleware } from '@reduxjs/toolkit'
2+
3+
export const listenerMiddleware = createListenerMiddleware()
4+
5+
export const { clearListeners, middleware, startListening, stopListening } =
6+
listenerMiddleware
7+
8+
export const { withTypes } = startListening
9+
10+
export const { withTypes: _withTypes } = stopListening

0 commit comments

Comments
 (0)