Skip to content

Commit 00b1db1

Browse files
authored
Add support for React 18 (#1808)
Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com>
1 parent 4afc80c commit 00b1db1

File tree

19 files changed

+393
-379
lines changed

19 files changed

+393
-379
lines changed

docs/_component/editor.client.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useState, useMemo, createElement, memo, useCallback} from 'react'
22
import {useDebounceFn} from 'ahooks'
3-
import * as runtime from 'react/jsx-runtime.js'
3+
import * as runtime from 'react/jsx-runtime'
44
import {VFile} from 'vfile'
55
import {VFileMessage} from 'vfile-message'
66
import {statistics} from 'vfile-statistics'

docs/migrating/v2.server.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ You can update your code as follows:
402402
After:
403403
404404
```js path="new.js"
405-
import * as runtime from 'react/jsx-runtime.js'
405+
import * as runtime from 'react/jsx-runtime'
406406
import * as provider from '@mdx-js/react'
407407
import {evaluate} from '@mdx-js/mdx'
408408

@@ -431,7 +431,7 @@ Using Emotion as an example:
431431
432432
```js path="new-emotion.js"
433433
//
434-
import * as runtime from '@emotion/react/jsx-runtime.js'
434+
import * as runtime from '@emotion/react/jsx-runtime'
435435
//
436436
```
437437

package-lock.json

Lines changed: 307 additions & 307 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
],
173173
"prettier": true,
174174
"rules": {
175+
"import/extensions": "off",
175176
"node/file-extension-in-import": "off",
176177
"react/prop-types": "off",
177178
"unicorn/prefer-node-protocol": "off",

packages/esbuild/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
"@types/react-dom": "^17.0.0",
5151
"@types/unist": "^2.0.0",
5252
"esbuild": "^0.13.0",
53-
"react": "^17.0.0",
54-
"react-dom": "^17.0.0",
53+
"react": "^18.0.0-alpha-327d5c484-20211106",
54+
"react-dom": "^18.0.0-alpha-327d5c484-20211106",
5555
"vfile-message": "^3.0.0"
5656
},
5757
"scripts": {

packages/loader/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
"babel-loader": "^8.0.0",
6060
"preact": "^10.0.0",
6161
"preact-render-to-string": "^5.0.0",
62-
"react": "^17.0.0",
63-
"react-dom": "^17.0.0",
62+
"react": "^18.0.0-alpha-327d5c484-20211106",
63+
"react-dom": "^18.0.0-alpha-327d5c484-20211106",
6464
"vue": "^3.0.0",
6565
"webpack": "^5.0.0"
6666
},

packages/mdx/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@
6464
"nanoid": "^3.0.0",
6565
"preact": "^10.0.0",
6666
"preact-render-to-string": "^5.0.0",
67-
"react": "^17.0.0",
68-
"react-dom": "^17.0.0",
67+
"react": "^18.0.0-alpha-327d5c484-20211106",
68+
"react-dom": "^18.0.0-alpha-327d5c484-20211106",
6969
"rehype-katex": "^6.0.0",
7070
"rehype-raw": "^6.0.0",
7171
"remark-frontmatter": "^4.0.0",

packages/mdx/readme.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ They come from an automatic JSX runtime that you must import yourself.
688688
<summary>Example</summary>
689689

690690
```js
691-
import * as runtime from 'react/jsx-runtime.js'
691+
import * as runtime from 'react/jsx-runtime'
692692

693693
const {default: Content} = await evaluate('# hi', {...runtime, ...otherOptions})
694694
```
@@ -704,7 +704,7 @@ Needed if you want to support a provider.
704704

705705
```js
706706
import * as provider from '@mdx-js/react'
707-
import * as runtime from 'react/jsx-runtime.js'
707+
import * as runtime from 'react/jsx-runtime'
708708

709709
const {default: Content} = await evaluate('# hi', {...provider, ...runtime, ...otherOptions})
710710
```
@@ -723,7 +723,7 @@ that was exported from the MDX file available too.
723723
Assuming the contents of `example.mdx` from [§ Use][use] was in `file`, then:
724724

725725
```js
726-
import * as runtime from 'react/jsx-runtime.js'
726+
import * as runtime from 'react/jsx-runtime'
727727
import {evaluate} from '@mdx-js/mdx'
728728

729729
console.log(await evaluate(file, {...runtime}))

packages/mdx/test/compile.js

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ test('compile', async () => {
145145
'should support the automatic runtime (`@jsxRuntime`)'
146146
)
147147

148-
console.log(
149-
'\nnote: the next deprecation is expected (preact is missing an export map)\n'
150-
)
151-
148+
// console.log(
149+
// '\nnote: the next deprecation is expected (preact is missing an export map)\n'
150+
// )
151+
//
152152
// To do: re-enable when `preact/compat` has a correct export map.
153153
// assert.equal(
154154
// render(
@@ -178,12 +178,7 @@ test('compile', async () => {
178178

179179
assert.equal(
180180
render(
181-
h(
182-
await run(compileSync('<>1</>', {jsxImportSource: 'preact'}), {
183-
keepImport: true
184-
}),
185-
{}
186-
)
181+
h(await run(compileSync('<>1</>', {jsxImportSource: 'preact'})), {})
187182
),
188183
'1',
189184
'should support `jsxImportSource` for `preact`'
@@ -198,8 +193,7 @@ test('compile', async () => {
198193
).replace(
199194
/\/jsx-runtime(?=["'])/g,
200195
'$&/dist/emotion-react-jsx-runtime.cjs.prod.js'
201-
),
202-
{keepImport: true}
196+
)
203197
)
204198
)
205199
),
@@ -947,7 +941,7 @@ test('markdown (GFM, with `remark-gfm`)', async () => {
947941
await run(compileSync('* [x] a\n* [ ] b', {remarkPlugins: [remarkGfm]}))
948942
)
949943
),
950-
'<ul class="contains-task-list">\n<li class="task-list-item"><input type="checkbox" checked="" disabled=""/> a</li>\n<li class="task-list-item"><input type="checkbox" disabled=""/> b</li>\n</ul>',
944+
'<ul class="contains-task-list">\n<li class="task-list-item"><input type="checkbox" disabled="" checked=""/> a</li>\n<li class="task-list-item"><input type="checkbox" disabled=""/> b</li>\n</ul>',
951945
'should support task lists (`* [x]` -> `input`)'
952946
)
953947

@@ -1322,10 +1316,7 @@ test('source maps', async () => {
13221316
Buffer.from(JSON.stringify(file.map)).toString('base64') +
13231317
'\n'
13241318

1325-
await fs.writeFile(
1326-
path.join(base, 'sourcemap.js'),
1327-
String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')
1328-
)
1319+
await fs.writeFile(path.join(base, 'sourcemap.js'), String(file))
13291320

13301321
const Content = /** @type {MDXContent} */ (
13311322
/* @ts-expect-error file is dynamically generated */
@@ -1356,32 +1347,21 @@ test.run()
13561347
/**
13571348
*
13581349
* @param {VFileCompatible} input
1359-
* @param {{keepImport?: boolean}} [options]
13601350
* @return {Promise<MDXContent>}
13611351
*/
1362-
async function run(input, options = {}) {
1363-
return (await runWhole(input, options)).default
1352+
async function run(input) {
1353+
return (await runWhole(input)).default
13641354
}
13651355

13661356
/**
13671357
*
13681358
* @param {VFileCompatible} input
1369-
* @param {{keepImport?: boolean}} [options]
13701359
* @return {Promise<MDXModule>}
13711360
*/
1372-
async function runWhole(input, options = {}) {
1361+
async function runWhole(input) {
13731362
const name = 'fixture-' + nanoid().toLowerCase() + '.js'
13741363
const fp = path.join('test', 'context', name)
1375-
let doc = String(input)
1376-
1377-
// Extensionless imports only work in faux-ESM (webpack and such),
1378-
// *not* in Node by default: *except* if there’s an export map defined
1379-
// in `package.json`.
1380-
// React doesn’t have one yet (it’s on `master` but not yet released), so add
1381-
// the extension for ’em:
1382-
if (!options.keepImport) {
1383-
doc = doc.replace(/\/jsx-runtime(?=["'])/g, '$&.js')
1384-
}
1364+
const doc = String(input)
13851365

13861366
await fs.writeFile(fp, doc)
13871367

packages/node-loader/lib/index.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
/**
22
* @typedef {import('@mdx-js/mdx/lib/compile.js').CompileOptions} CompileOptions
3+
*
4+
* @typedef LoaderOptions
5+
* @property {boolean} [fixRuntimeWithoutExportMap=true]
6+
* Several JSX runtimes, notably React and Emotion, don’t yet have a proper
7+
* export map set up.
8+
* Export maps are needed to map `xxx/jsx-runtime` to an actual file in ESM.
9+
* This option fixes React et al by turning those into `xxx/jsx-runtime.js`.
10+
*
11+
* @typedef {CompileOptions & LoaderOptions} Options
312
*/
413

514
import {promises as fs} from 'node:fs'
@@ -11,10 +20,18 @@ import {createFormatAwareProcessors} from '@mdx-js/mdx/lib/util/create-format-aw
1120
/**
1221
* Create smart processors to handle different formats.
1322
*
14-
* @param {CompileOptions} [options]
23+
* @param {Options} [options]
1524
*/
16-
export function createLoader(options) {
25+
export function createLoader(options = {}) {
1726
const {extnames, process} = createFormatAwareProcessors(options)
27+
let fixRuntimeWithoutExportMap = options.fixRuntimeWithoutExportMap
28+
29+
if (
30+
fixRuntimeWithoutExportMap === null ||
31+
fixRuntimeWithoutExportMap === undefined
32+
) {
33+
fixRuntimeWithoutExportMap = true
34+
}
1835

1936
return {load, getFormat, transformSource}
2037

@@ -30,16 +47,16 @@ export function createLoader(options) {
3047
return defaultLoad(url, context, defaultLoad)
3148
}
3249

33-
const fp = fileURLToPath(new URL(url))
34-
const value = await fs.readFile(fp)
50+
/* eslint-disable-next-line security/detect-non-literal-fs-filename */
51+
const value = await fs.readFile(fileURLToPath(new URL(url)))
3552
const file = await process(new VFile({value, path: new URL(url)}))
53+
let source = String(file)
3654

37-
// V8 on Erbium.
38-
/* c8 ignore next 2 */
39-
return {
40-
format: 'module',
41-
source: String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')
55+
if (fixRuntimeWithoutExportMap) {
56+
source = String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')
4257
}
58+
59+
return {format: 'module', source}
4360
}
4461

4562
// Pre version 17.
@@ -69,9 +86,13 @@ export function createLoader(options) {
6986
}
7087

7188
const file = await process(new VFile({value, path: new URL(context.url)}))
72-
// V8 on Erbium.
73-
/* c8 ignore next 2 */
74-
return {source: String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')}
89+
let source = String(file)
90+
91+
if (fixRuntimeWithoutExportMap) {
92+
source = String(file).replace(/\/jsx-runtime(?=["'])/g, '$&.js')
93+
}
94+
95+
return {source}
7596
}
7697
/* c8 ignore end */
7798
}

0 commit comments

Comments
 (0)