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

ESM compliant bundling #3521

Merged
merged 19 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { NODE_ENV, BABEL_ENV } = process.env
const cjs = NODE_ENV === 'test' || BABEL_ENV === 'commonjs'
const es = BABEL_ENV === 'es'
const loose = true

module.exports = {
Expand All @@ -20,10 +21,11 @@ module.exports = {
],
plugins: [
cjs && ['@babel/transform-modules-commonjs', { loose }],
[
es && ['babel-plugin-add-import-extension', { extension: 'mjs' }],
// no runtime for umd builds
BABEL_ENV && [
'@babel/transform-runtime',
{
useESModules: !cjs,
version: require('./package.json').dependencies[
'@babel/runtime'
].replace(/^[^0-9]*/, ''),
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [12, 14, 16]
node: [14, 16]
react: [17, 18]
steps:
- uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions broadcastQueryClient-experimental/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/broadcastQueryClient-experimental'
1 change: 1 addition & 0 deletions broadcastQueryClient-experimental/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../lib/broadcastQueryClient-experimental/index')
1 change: 1 addition & 0 deletions core/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/core'
1 change: 1 addition & 0 deletions core/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../lib/core/index')
6 changes: 0 additions & 6 deletions core/package.json

This file was deleted.

1 change: 1 addition & 0 deletions createAsyncStoragePersister/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/createAsyncStoragePersister'
1 change: 1 addition & 0 deletions createAsyncStoragePersister/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../lib/createAsyncStoragePersister/index')
6 changes: 0 additions & 6 deletions createAsyncStoragePersister/package.json

This file was deleted.

1 change: 1 addition & 0 deletions createWebStoragePersister/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/createWebStoragePersister'
1 change: 1 addition & 0 deletions createWebStoragePersister/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../lib/createWebStoragePersister/index')
6 changes: 0 additions & 6 deletions createWebStoragePersister/package.json

This file was deleted.

1 change: 1 addition & 0 deletions devtools/development/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../../lib/devtools'
1 change: 1 addition & 0 deletions devtools/development/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../lib/devtools/index')
6 changes: 0 additions & 6 deletions devtools/development/package.json

This file was deleted.

1 change: 1 addition & 0 deletions devtools/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/devtools'
11 changes: 2 additions & 9 deletions devtools/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
if (process.env.NODE_ENV !== 'development') {
module.exports = {
ReactQueryDevtools: function () {
return null
},
ReactQueryDevtoolsPanel: function () {
return null
},
}
module.exports = require('../lib/devtools/noop')
} else {
module.exports = require('./development')
module.exports = require('../lib/devtools/index')
}
6 changes: 0 additions & 6 deletions devtools/package.json

This file was deleted.

48 changes: 26 additions & 22 deletions docs/src/pages/guides/migrating-to-react-query-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ title: Migrating to React Query 4

## Breaking Changes

### ESM Support

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.

### Query Keys (and Mutation Keys) need to be an Array

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.
Expand Down Expand Up @@ -222,12 +226,12 @@ Even though React Query is an Async State Manager that can be used for anything
new QueryClient({
defaultOptions: {
queries: {
networkMode: 'offlineFirst'
networkMode: 'offlineFirst',
},
mutations: {
networkmode: 'offlineFirst'
}
}
networkmode: 'offlineFirst',
},
},
})
```

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


### Removed undocumented methods from the `queryClient`, `query` and `mutation`

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`
Expand Down Expand Up @@ -289,10 +292,7 @@ In order to make bailing out of updates possible by returning `undefined`, we ha
Further, it is an easy bug to produce `Promise<void>` by adding logging in the queryFn:

```js
useQuery(
['key'],
() => axios.get(url).then(result => console.log(result.data))
)
useQuery(['key'], () => axios.get(url).then(result => console.log(result.data)))
```

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.
Expand Down Expand Up @@ -349,19 +349,18 @@ React Query defaults to "tracking" query properties, which should give you a nic
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:

```js
queryClient.setQueryData(
['todo', id],
(previousTodo) => previousTodo ? { ...previousTodo, done: true } : undefined
queryClient.setQueryData(['todo', id], previousTodo =>
previousTodo ? { ...previousTodo, done: true } : undefined
)
```
```

### Custom Contexts for Multiple Providers
### Custom Contexts for Multiple Providers

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.

An example:

1) Create a data package.
1. Create a data package.

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

export const ContainerDataProvider = ({ children }: { children: React.ReactNode}) => {
export const ContainerDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}

```

2) Create a second data package.
2. Create a second data package.

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

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


export const useItems = () => {
return useQuery(ITEMS_KEY, ITEMS_FETCHER, {
context,
})
}

export const MyComponentDataProvider = ({ children }: { children: React.ReactNode}) => {
export const MyComponentDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}

```

3) Use these two data packages in your application.
3. Use these two data packages in your application.

```tsx
// Our application
Expand Down
99 changes: 68 additions & 31 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,60 @@
"url": "https://github.com/sponsors/tannerlinsley"
},
"main": "lib/index.js",
"module": "lib/index.mjs",
"types": "lib/index.d.ts",
"unpkg": "dist/react-query.development.js",
"types": "types/index.d.ts",
"module": "es/index.js",
"sideEffects": [
"es/index.js",
"es/reactjs/index.js",
"es/reactjs/setBatchUpdatesFn.js",
"lib/index.js",
"lib/index.mjs",
"lib/reactjs/index.js",
"lib/reactjs/setBatchUpdatesFn.js"
"lib/reactjs/index.mjs",
"lib/reactjs/setBatchUpdatesFn.js",
"lib/reactjs/setBatchUpdatesFn.mjs"
],
"exports": {
".": {
"import": "./lib/index.mjs",
"default": "./lib/index.js"
},
"./package.json": "./package.json",
"./core": {
"import": "./lib/core/index.mjs",
"default": "./lib/core/index.js"
},
"./reactjs": {
"import": "./lib/reactjs/index.mjs",
"default": "./lib/reactjs/index.js"
},
"./devtools": {
"development": {
sachinraja marked this conversation as resolved.
Show resolved Hide resolved
"import": "./lib/devtools/index.mjs",
"default": "./lib/devtools/index.js"
},
"import": "./lib/devtools/noop.mjs",
"default": "./lib/devtools/noop.js"
},
"./devtools/development": {
"import": "./lib/devtools/index.mjs",
"default": "./lib/devtools/index.js"
},
"./persistQueryClient": {
"import": "./lib/persistQueryClient/index.mjs",
"default": "./lib/persistQueryClient/index.js"
},
"./createWebStoragePersister": {
"import": "./lib/createWebStoragePersister/index.mjs",
"default": "./lib/createWebStoragePersister/index.js"
},
"./createAsyncStoragePersister": {
"import": "./lib/createAsyncStoragePersister/index.mjs",
"default": "./lib/createAsyncStoragePersister/index.js"
},
"./broadcastQueryClient-experimental": {
"import": "./lib/broadcastQueryClient-experimental/index.mjs",
"default": "./lib/broadcastQueryClient-experimental/index.js"
}
},
"scripts": {
"test": "is-ci \"test:ci\" \"test:dev\"",
"test:dev": "npm run test:types && npm run test:format && npm run test:eslint && npm run test:codemod && jest --watch",
Expand All @@ -34,42 +77,38 @@
"test:size": "yarn build:umd && bundlewatch",
"test:codemod": "jest --config codemods/jest.config.js",
"build": "yarn build:commonjs && yarn build:es && yarn build:umd && yarn build:types",
"build:commonjs": "rimraf ./lib && cross-env BABEL_ENV=commonjs babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
"build:es": "rimraf ./es && babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir es",
"build:commonjs": "rimraf './lib/**/*.js' && cross-env BABEL_ENV=commonjs babel --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
"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",
"build:umd": "rimraf ./dist && cross-env NODE_ENV=production rollup -c && rollup-plugin-visualizer stats-react.json",
"build:types": "rimraf ./types && tsc --project ./tsconfig.types.json && replace 'import type' 'import' ./types -r --silent && replace 'export type' 'export' ./types -r --silent",
"watch": "yarn watch:commonjs & yarn watch:es & yarn watch:umd & yarn watch:types",
"watch:commonjs": "rimraf ./lib && cross-env BABEL_ENV=commonjs babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
"watch:es": "rimraf ./es && babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir es",
"build:types": "rimraf './lib/**/*.d.ts' && tsc --project ./tsconfig.types.json",
"watch": "yarn watch:commonjs && watch:es & yarn watch:umd & yarn watch:types",
"watch:commonjs": "rimraf './lib/**/*.js' && cross-env BABEL_ENV=commonjs babel --watch --extensions .ts,.tsx --ignore ./src/**/tests/**/* ./src --out-dir lib",
"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",
"watch:umd": "rimraf ./dist && cross-env NODE_ENV=production rollup -w -c && rollup-plugin-visualizer stats-react.json",
"watch:types": "rimraf ./types && tsc --watch --project ./tsconfig.types.json && replace 'import type' 'import' ./types -r --silent && replace 'export type' 'export' ./types -r --silent",
"watch:types": "rimraf './lib/**/*.d.ts' && tsc --watch --project ./tsconfig.types.json",
"now-build": "yarn && cd www && yarn && yarn build",
"prettier": "prettier \"{.,src,src/**,example/src,example/src/**,types}/*.{md,js,jsx,ts,tsx,json}\"",
"start": "yarn watch",
"format": "yarn prettier --write",
"stats": "open ./stats.html"
},
"files": [
"core",
"dist",
"es",
"hydration",
"lib",
"core",
"devtools",
"persistQueryClient",
"createWebStoragePersister",
"createAsyncStoragePersister",
"broadcastQueryClient-experimental",
"lib",
"reactjs",
"scripts",
"types",
"codemods",
"!codemods/jest.config.js",
"!codemods/**/__testfixtures__",
"!codemods/**/__tests__"
],
"dependencies": {
"@babel/runtime": "^7.5.5",
"@babel/runtime": "^7.17.9",
"@types/use-sync-external-store": "^0.0.3",
"broadcast-channel": "^3.4.1",
"match-sorter": "^6.0.2",
Expand All @@ -88,16 +127,18 @@
},
"devDependencies": {
"@babel/cli": "^7.17.6",
"@babel/core": "^7.17.5",
"@babel/core": "^7.17.9",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@rollup/plugin-replace": "^3.0.0",
"@svgr/rollup": "^6.1.1",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "21.1.0",
"@rollup/plugin-node-resolve": "^13.2.1",
"@rollup/plugin-replace": "^4.0.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/react-17": "npm:@testing-library/react@^12.1.4",
"@testing-library/jest-dom": "^5.14.1",
"@types/jest": "^26.0.4",
"@types/jscodeshift": "^0.11.3",
"@types/node": "^16.11.10",
Expand All @@ -107,6 +148,7 @@
"@typescript-eslint/parser": "^5.6.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.0.1",
"babel-plugin-add-import-extension": "^1.6.0",
"bundlewatch": "^0.3.2",
"cross-env": "^7.0.2",
"eslint": "7.x",
Expand Down Expand Up @@ -134,13 +176,8 @@
"react-error-boundary": "^3.1.4",
"replace": "^1.2.0",
"rimraf": "^3.0.2",
"rollup": "^2.68.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-jscc": "^2.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-prettier": "^2.2.2",
"rollup": "^2.70.2",
"rollup-plugin-node-externals": "^4.0.0",
"rollup-plugin-size": "^0.2.2",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.6.0",
Expand Down
1 change: 1 addition & 0 deletions persistQueryClient/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../lib/persistQueryClient'
Loading