Skip to content

Commit 3fabd41

Browse files
authored
fix: ESM compliant bundling (#3521)
* fix various bundling issues * add package.json to exports * remove @svgr/rollup * remove node v12 from CI * support devtools/development * do not alias react-query * add side effect * remove "module" * fix * fix exports * add "module" * update @babel/runtime * don't preserve modules * switch back to babel * add migration note * update babel * update rollup * downgrade @rollup/plugin-commonjs
1 parent 1af25c6 commit 3fabd41

File tree

31 files changed

+427
-1326
lines changed

31 files changed

+427
-1326
lines changed

.babelrc.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { NODE_ENV, BABEL_ENV } = process.env
22
const cjs = NODE_ENV === 'test' || BABEL_ENV === 'commonjs'
3+
const es = BABEL_ENV === 'es'
34
const loose = true
45

56
module.exports = {
@@ -20,10 +21,11 @@ module.exports = {
2021
],
2122
plugins: [
2223
cjs && ['@babel/transform-modules-commonjs', { loose }],
23-
[
24+
es && ['babel-plugin-add-import-extension', { extension: 'mjs' }],
25+
// no runtime for umd builds
26+
BABEL_ENV && [
2427
'@babel/transform-runtime',
2528
{
26-
useESModules: !cjs,
2729
version: require('./package.json').dependencies[
2830
'@babel/runtime'
2931
].replace(/^[^0-9]*/, ''),

.github/workflows/test-and-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
strategy:
1919
matrix:
20-
node: [12, 14, 16]
20+
node: [14, 16]
2121
react: [17, 18]
2222
steps:
2323
- uses: actions/checkout@v2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/broadcastQueryClient-experimental'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../lib/broadcastQueryClient-experimental/index')

core/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/core'

core/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../lib/core/index')

core/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/createAsyncStoragePersister'

createAsyncStoragePersister/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../lib/createAsyncStoragePersister/index')

createAsyncStoragePersister/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

createWebStoragePersister/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/createWebStoragePersister'

createWebStoragePersister/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../lib/createWebStoragePersister/index')

createWebStoragePersister/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

devtools/development/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../../lib/devtools'

devtools/development/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../lib/devtools/index')

devtools/development/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

devtools/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/devtools'

devtools/index.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
if (process.env.NODE_ENV !== 'development') {
2-
module.exports = {
3-
ReactQueryDevtools: function () {
4-
return null
5-
},
6-
ReactQueryDevtoolsPanel: function () {
7-
return null
8-
},
9-
}
2+
module.exports = require('../lib/devtools/noop')
103
} else {
11-
module.exports = require('./development')
4+
module.exports = require('../lib/devtools/index')
125
}

devtools/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs/src/pages/guides/migrating-to-react-query-4.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ title: Migrating to React Query 4
55

66
## Breaking Changes
77

8+
### ESM Support
9+
10+
React Query now supports [package.json `"exports"`](https://nodejs.org/api/packages.html#exports) and is fully compatible with Node's native resolution for both CommonJS and ESM. We don't expect this to be a breaking change for most users, but this restricts the files you can import into your project to only the entry points we officially support.
11+
812
### Query Keys (and Mutation Keys) need to be an Array
913

1014
In v3, Query and Mutation Keys could be a String or an Array. Internally, React Query has always worked with Array Keys only, and we've sometimes exposed this to consumers. For example, in the `queryFn`, you would always get the key as an Array to make working with [Default Query Functions](./default-query-function) easier.
@@ -222,12 +226,12 @@ Even though React Query is an Async State Manager that can be used for anything
222226
new QueryClient({
223227
defaultOptions: {
224228
queries: {
225-
networkMode: 'offlineFirst'
229+
networkMode: 'offlineFirst',
226230
},
227231
mutations: {
228-
networkmode: 'offlineFirst'
229-
}
230-
}
232+
networkmode: 'offlineFirst',
233+
},
234+
},
231235
})
232236
```
233237

@@ -240,7 +244,6 @@ The `useQueries` hook now accepts an object with a `queries` prop as its input.
240244
+ useQueries({ queries: [{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }] })
241245
```
242246

243-
244247
### Removed undocumented methods from the `queryClient`, `query` and `mutation`
245248

246249
The methods `cancelMutatations` and `executeMutation` on the `QueryClient` were undocumented and unused internally, so we removed them. Since it was just a wrapper around a method available on the `mutationCache`, you can still use the functionality of `executeMutation`
@@ -289,10 +292,7 @@ In order to make bailing out of updates possible by returning `undefined`, we ha
289292
Further, it is an easy bug to produce `Promise<void>` by adding logging in the queryFn:
290293

291294
```js
292-
useQuery(
293-
['key'],
294-
() => axios.get(url).then(result => console.log(result.data))
295-
)
295+
useQuery(['key'], () => axios.get(url).then(result => console.log(result.data)))
296296
```
297297

298298
This is now disallowed on type level; at runtime, `undefined` will be transformed to a _failed Promise_, which means you will get an `error`, which will also be logged to the console in development mode.
@@ -349,19 +349,18 @@ React Query defaults to "tracking" query properties, which should give you a nic
349349
When using the [functional updater form of setQueryData](../reference/QueryClient#queryclientsetquerydata), you can now bail out of the update by returning `undefined`. This is helpful if `undefined` is given to you as `previousValue`, which means that currently, no cached entry exists and you don't want to / cannot create one, like in the example of toggling a todo:
350350

351351
```js
352-
queryClient.setQueryData(
353-
['todo', id],
354-
(previousTodo) => previousTodo ? { ...previousTodo, done: true } : undefined
352+
queryClient.setQueryData(['todo', id], previousTodo =>
353+
previousTodo ? { ...previousTodo, done: true } : undefined
355354
)
356-
```
355+
```
357356

358-
### Custom Contexts for Multiple Providers
357+
### Custom Contexts for Multiple Providers
359358

360359
Custom contexts can now be specified to pair hooks with their matching `Provider`. This is critical when there may be multiple React Query `Provider` instances in the component tree, and you need to ensure your hook uses the correct `Provider` instance.
361360

362361
An example:
363362

364-
1) Create a data package.
363+
1. Create a data package.
365364

366365
```tsx
367366
// Our first data package: @my-scope/container-data
@@ -375,42 +374,47 @@ export const useUser = () => {
375374
})
376375
}
377376

378-
export const ContainerDataProvider = ({ children }: { children: React.ReactNode}) => {
377+
export const ContainerDataProvider = ({
378+
children,
379+
}: {
380+
children: React.ReactNode
381+
}) => {
379382
return (
380383
<QueryClientProvider client={queryClient} context={context}>
381384
{children}
382385
</QueryClientProvider>
383386
)
384387
}
385-
386388
```
387389

388-
2) Create a second data package.
390+
2. Create a second data package.
389391

390392
```tsx
391393
// Our second data package: @my-scope/my-component-data
392394

393395
const context = React.createContext<QueryClient | undefined>(undefined)
394396
const queryClient = new QueryClient()
395397

396-
397398
export const useItems = () => {
398399
return useQuery(ITEMS_KEY, ITEMS_FETCHER, {
399400
context,
400401
})
401402
}
402403

403-
export const MyComponentDataProvider = ({ children }: { children: React.ReactNode}) => {
404+
export const MyComponentDataProvider = ({
405+
children,
406+
}: {
407+
children: React.ReactNode
408+
}) => {
404409
return (
405410
<QueryClientProvider client={queryClient} context={context}>
406411
{children}
407412
</QueryClientProvider>
408413
)
409414
}
410-
411415
```
412416

413-
3) Use these two data packages in your application.
417+
3. Use these two data packages in your application.
414418

415419
```tsx
416420
// Our application

package.json

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,60 @@
1111
"url": "https://github.com/sponsors/tannerlinsley"
1212
},
1313
"main": "lib/index.js",
14+
"module": "lib/index.mjs",
15+
"types": "lib/index.d.ts",
1416
"unpkg": "dist/react-query.development.js",
15-
"types": "types/index.d.ts",
16-
"module": "es/index.js",
1717
"sideEffects": [
18-
"es/index.js",
19-
"es/reactjs/index.js",
20-
"es/reactjs/setBatchUpdatesFn.js",
2118
"lib/index.js",
19+
"lib/index.mjs",
2220
"lib/reactjs/index.js",
23-
"lib/reactjs/setBatchUpdatesFn.js"
21+
"lib/reactjs/index.mjs",
22+
"lib/reactjs/setBatchUpdatesFn.js",
23+
"lib/reactjs/setBatchUpdatesFn.mjs"
2424
],
25+
"exports": {
26+
".": {
27+
"import": "./lib/index.mjs",
28+
"default": "./lib/index.js"
29+
},
30+
"./package.json": "./package.json",
31+
"./core": {
32+
"import": "./lib/core/index.mjs",
33+
"default": "./lib/core/index.js"
34+
},
35+
"./reactjs": {
36+
"import": "./lib/reactjs/index.mjs",
37+
"default": "./lib/reactjs/index.js"
38+
},
39+
"./devtools": {
40+
"development": {
41+
"import": "./lib/devtools/index.mjs",
42+
"default": "./lib/devtools/index.js"
43+
},
44+
"import": "./lib/devtools/noop.mjs",
45+
"default": "./lib/devtools/noop.js"
46+
},
47+
"./devtools/development": {
48+
"import": "./lib/devtools/index.mjs",
49+
"default": "./lib/devtools/index.js"
50+
},
51+
"./persistQueryClient": {
52+
"import": "./lib/persistQueryClient/index.mjs",
53+
"default": "./lib/persistQueryClient/index.js"
54+
},
55+
"./createWebStoragePersister": {
56+
"import": "./lib/createWebStoragePersister/index.mjs",
57+
"default": "./lib/createWebStoragePersister/index.js"
58+
},
59+
"./createAsyncStoragePersister": {
60+
"import": "./lib/createAsyncStoragePersister/index.mjs",
61+
"default": "./lib/createAsyncStoragePersister/index.js"
62+
},
63+
"./broadcastQueryClient-experimental": {
64+
"import": "./lib/broadcastQueryClient-experimental/index.mjs",
65+
"default": "./lib/broadcastQueryClient-experimental/index.js"
66+
}
67+
},
2568
"scripts": {
2669
"test": "is-ci \"test:ci\" \"test:dev\"",
2770
"test:dev": "npm run test:types && npm run test:format && npm run test:eslint && npm run test:codemod && jest --watch",
@@ -34,42 +77,38 @@
3477
"test:size": "yarn build:umd && bundlewatch",
3578
"test:codemod": "jest --config codemods/jest.config.js",
3679
"build": "yarn build:commonjs && yarn build:es && yarn build:umd && yarn build:types",
37-
"build:commonjs": "rimraf ./lib && cross-env BABEL_ENV=commonjs babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
38-
"build:es": "rimraf ./es && babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir es",
80+
"build:commonjs": "rimraf './lib/**/*.js' && cross-env BABEL_ENV=commonjs babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
81+
"build:es": "rimraf './lib/**/*.mjs' && cross-env BABEL_ENV=es babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib --out-file-extension .mjs",
3982
"build:umd": "rimraf ./dist && cross-env NODE_ENV=production rollup -c && rollup-plugin-visualizer stats-react.json",
40-
"build:types": "rimraf ./types && tsc --project ./tsconfig.types.json && replace 'import type' 'import' ./types -r --silent && replace 'export type' 'export' ./types -r --silent",
41-
"watch": "yarn watch:commonjs & yarn watch:es & yarn watch:umd & yarn watch:types",
42-
"watch:commonjs": "rimraf ./lib && cross-env BABEL_ENV=commonjs babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
43-
"watch:es": "rimraf ./es && babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir es",
83+
"build:types": "rimraf './lib/**/*.d.ts' && tsc --project ./tsconfig.types.json",
84+
"watch": "yarn watch:commonjs && watch:es & yarn watch:umd & yarn watch:types",
85+
"watch:commonjs": "rimraf './lib/**/*.js' && cross-env BABEL_ENV=commonjs babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
86+
"watch:es": "rimraf './lib/**/*.mjs' && cross-env BABEL_ENV=es babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib --out-file-extension .mjs",
4487
"watch:umd": "rimraf ./dist && cross-env NODE_ENV=production rollup -w -c && rollup-plugin-visualizer stats-react.json",
45-
"watch:types": "rimraf ./types && tsc --watch --project ./tsconfig.types.json && replace 'import type' 'import' ./types -r --silent && replace 'export type' 'export' ./types -r --silent",
88+
"watch:types": "rimraf './lib/**/*.d.ts' && tsc --watch --project ./tsconfig.types.json",
4689
"now-build": "yarn && cd www && yarn && yarn build",
4790
"prettier": "prettier \"{.,src,src/**,example/src,example/src/**,types}/*.{md,js,jsx,ts,tsx,json}\"",
4891
"start": "yarn watch",
4992
"format": "yarn prettier --write",
5093
"stats": "open ./stats.html"
5194
},
5295
"files": [
53-
"core",
5496
"dist",
55-
"es",
56-
"hydration",
97+
"lib",
98+
"core",
5799
"devtools",
58100
"persistQueryClient",
59101
"createWebStoragePersister",
60102
"createAsyncStoragePersister",
61103
"broadcastQueryClient-experimental",
62-
"lib",
63104
"reactjs",
64-
"scripts",
65-
"types",
66105
"codemods",
67106
"!codemods/jest.config.js",
68107
"!codemods/**/__testfixtures__",
69108
"!codemods/**/__tests__"
70109
],
71110
"dependencies": {
72-
"@babel/runtime": "^7.5.5",
111+
"@babel/runtime": "^7.17.9",
73112
"@types/use-sync-external-store": "^0.0.3",
74113
"broadcast-channel": "^3.4.1",
75114
"match-sorter": "^6.0.2",
@@ -88,16 +127,18 @@
88127
},
89128
"devDependencies": {
90129
"@babel/cli": "^7.17.6",
91-
"@babel/core": "^7.17.5",
130+
"@babel/core": "^7.17.9",
92131
"@babel/plugin-transform-runtime": "^7.17.0",
93132
"@babel/preset-env": "^7.16.11",
94133
"@babel/preset-react": "^7.16.7",
95134
"@babel/preset-typescript": "^7.16.7",
96-
"@rollup/plugin-replace": "^3.0.0",
97-
"@svgr/rollup": "^6.1.1",
135+
"@rollup/plugin-babel": "^5.3.1",
136+
"@rollup/plugin-commonjs": "21.1.0",
137+
"@rollup/plugin-node-resolve": "^13.2.1",
138+
"@rollup/plugin-replace": "^4.0.0",
139+
"@testing-library/jest-dom": "^5.14.1",
98140
"@testing-library/react": "^13.0.0",
99141
"@testing-library/react-17": "npm:@testing-library/react@^12.1.4",
100-
"@testing-library/jest-dom": "^5.14.1",
101142
"@types/jest": "^26.0.4",
102143
"@types/jscodeshift": "^0.11.3",
103144
"@types/node": "^16.11.10",
@@ -107,6 +148,7 @@
107148
"@typescript-eslint/parser": "^5.6.0",
108149
"babel-eslint": "^10.1.0",
109150
"babel-jest": "^26.0.1",
151+
"babel-plugin-add-import-extension": "^1.6.0",
110152
"bundlewatch": "^0.3.2",
111153
"cross-env": "^7.0.2",
112154
"eslint": "7.x",
@@ -134,13 +176,8 @@
134176
"react-error-boundary": "^3.1.4",
135177
"replace": "^1.2.0",
136178
"rimraf": "^3.0.2",
137-
"rollup": "^2.68.0",
138-
"rollup-plugin-babel": "^4.4.0",
139-
"rollup-plugin-commonjs": "^10.1.0",
140-
"rollup-plugin-jscc": "^2.0.0",
141-
"rollup-plugin-node-resolve": "^5.2.0",
142-
"rollup-plugin-peer-deps-external": "^2.2.4",
143-
"rollup-plugin-prettier": "^2.2.2",
179+
"rollup": "^2.70.2",
180+
"rollup-plugin-node-externals": "^4.0.0",
144181
"rollup-plugin-size": "^0.2.2",
145182
"rollup-plugin-terser": "^7.0.2",
146183
"rollup-plugin-visualizer": "^5.6.0",

persistQueryClient/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../lib/persistQueryClient'

0 commit comments

Comments
 (0)