-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
125 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# React | ||
|
||
```js echo | ||
import {createElement} from "react"; | ||
|
||
display(createElement); | ||
``` | ||
|
||
```js echo | ||
import {createRoot} from "react-dom/client"; | ||
|
||
display(createRoot); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,9 @@ import {existsSync} from "node:fs"; | |
import {copyFile, readFile, writeFile} from "node:fs/promises"; | ||
import {createRequire} from "node:module"; | ||
import op from "node:path"; | ||
import {extname, join} from "node:path/posix"; | ||
import {dirname, extname, join, relative} from "node:path/posix"; | ||
import {pathToFileURL} from "node:url"; | ||
import commonjs from "@rollup/plugin-commonjs"; | ||
import {nodeResolve} from "@rollup/plugin-node-resolve"; | ||
import {packageDirectory} from "pkg-dir"; | ||
import type {AstNode, OutputChunk, Plugin, ResolveIdResult} from "rollup"; | ||
|
@@ -12,7 +13,7 @@ import esbuild from "rollup-plugin-esbuild"; | |
import {prepareOutput, toOsPath} from "./files.js"; | ||
import type {ImportReference} from "./javascript/imports.js"; | ||
import {isJavaScript, parseImports} from "./javascript/imports.js"; | ||
import {parseNpmSpecifier} from "./npm.js"; | ||
import {parseNpmSpecifier, rewriteNpmImports} from "./npm.js"; | ||
import {isPathImport} from "./path.js"; | ||
import {faint} from "./tty.js"; | ||
|
||
|
@@ -38,7 +39,15 @@ async function resolveNodeImportInternal(cacheRoot: string, packageRoot: string, | |
process.stdout.write(`${spec} ${faint("→")} ${resolution}\n`); | ||
await prepareOutput(outputPath); | ||
if (isJavaScript(pathResolution)) { | ||
await writeFile(outputPath, await bundle(spec, cacheRoot, packageResolution)); | ||
await writeFile( | ||
outputPath, | ||
await bundle( | ||
`/_node/${resolution}`, | ||
overrideNodeResolution(spec, packageResolution), | ||
cacheRoot, | ||
packageResolution | ||
) | ||
); | ||
} else { | ||
await copyFile(pathResolution, outputPath); | ||
} | ||
|
@@ -51,6 +60,25 @@ async function resolveNodeImportInternal(cacheRoot: string, packageRoot: string, | |
return `/_node/${resolution}`; | ||
} | ||
|
||
/** | ||
* React (and its dependencies) are still distributed as CommonJS modules, which | ||
* means we lose named exports when we bundle them as an ES module — there’s | ||
* only a default export. We can fix this by importing the production bundle | ||
* instead, which is (by luck) compatible with cjs-module-lexer. This is quite | ||
* terrible, and I hope that the React team distributes ES modules soon. | ||
* | ||
* https://github.com/facebook/react/issues/11503 | ||
*/ | ||
function overrideNodeResolution(specifier: string, packageResolution: string): string { | ||
return specifier === "react" | ||
? op.join(packageResolution, "cjs", "react.production.min.js") | ||
: specifier === "react-dom" || specifier === "react-dom/client" | ||
? op.join(packageResolution, "cjs", "react-dom.production.min.js") | ||
: specifier === "scheduler" | ||
? op.join(packageResolution, "cjs", "scheduler.production.min.js") | ||
: specifier; | ||
} | ||
|
||
/** | ||
* Resolves the direct dependencies of the specified node import path, such as | ||
* "/_node/[email protected]/src/index.js", returning a set of node import paths. | ||
|
@@ -69,29 +97,34 @@ export function extractNodeSpecifier(path: string): string { | |
return path.replace(/^\/_node\//, ""); | ||
} | ||
|
||
async function bundle(input: string, cacheRoot: string, packageRoot: string): Promise<string> { | ||
async function bundle(path: string, input: string, cacheRoot: string, packageRoot: string): Promise<string> { | ||
const bundle = await rollup({ | ||
input, | ||
plugins: [ | ||
nodeResolve({browser: true, rootDir: packageRoot}), | ||
importResolve(input, cacheRoot, packageRoot), | ||
nodeResolve({browser: true, rootDir: packageRoot}), | ||
commonjs({esmExternals: true}), | ||
esbuild({ | ||
format: "esm", | ||
platform: "browser", | ||
target: ["es2022", "chrome96", "firefox96", "safari16", "node18"], | ||
exclude: [], // don’t exclude node_modules | ||
define: {"process.env.NODE_ENV": JSON.stringify("production")}, | ||
minify: true | ||
}) | ||
], | ||
external(source) { | ||
return source.startsWith("/_node/"); | ||
}, | ||
onwarn(message, warn) { | ||
if (message.code === "CIRCULAR_DEPENDENCY") return; | ||
warn(message); | ||
} | ||
}); | ||
try { | ||
const output = await bundle.generate({format: "es"}); | ||
const code = output.output.find((o): o is OutputChunk => o.type === "chunk")!.code; // TODO don’t assume one chunk? | ||
return code; | ||
const output = await bundle.generate({format: "es", exports: "named"}); | ||
const code = output.output.find((o): o is OutputChunk => o.type === "chunk")!.code; | ||
return rewriteNpmImports(code, (i) => (i.startsWith("/_node/") ? relative(dirname(path), i) : i)); | ||
} finally { | ||
await bundle.close(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -339,7 +339,7 @@ | |
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" | ||
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== | ||
|
||
"@jridgewell/sourcemap-codec@^1.4.14": | ||
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": | ||
version "1.4.15" | ||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" | ||
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== | ||
|
@@ -410,6 +410,18 @@ | |
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" | ||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== | ||
|
||
"@rollup/plugin-commonjs@^25.0.7": | ||
version "25.0.7" | ||
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz#145cec7589ad952171aeb6a585bbeabd0fd3b4cf" | ||
integrity sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ== | ||
dependencies: | ||
"@rollup/pluginutils" "^5.0.1" | ||
commondir "^1.0.1" | ||
estree-walker "^2.0.2" | ||
glob "^8.0.3" | ||
is-reference "1.2.1" | ||
magic-string "^0.30.3" | ||
|
||
"@rollup/plugin-node-resolve@^15.2.3": | ||
version "15.2.3" | ||
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" | ||
|
@@ -523,7 +535,7 @@ | |
resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90" | ||
integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== | ||
|
||
"@types/[email protected]", "@types/estree@^1.0.0": | ||
"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0": | ||
version "1.0.5" | ||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" | ||
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== | ||
|
@@ -1128,6 +1140,11 @@ commander@7: | |
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" | ||
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== | ||
|
||
commondir@^1.0.1: | ||
version "1.0.1" | ||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" | ||
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== | ||
|
||
component-emitter@^1.3.0: | ||
version "1.3.1" | ||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" | ||
|
@@ -1970,7 +1987,7 @@ glob-parent@^6.0.2: | |
dependencies: | ||
is-glob "^4.0.3" | ||
|
||
[email protected]: | ||
[email protected], glob@^8.0.3: | ||
version "8.1.0" | ||
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" | ||
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== | ||
|
@@ -2353,6 +2370,13 @@ is-potential-custom-element-name@^1.0.1: | |
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" | ||
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== | ||
|
||
[email protected]: | ||
version "1.2.1" | ||
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" | ||
integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== | ||
dependencies: | ||
"@types/estree" "*" | ||
|
||
is-regex@^1.1.4: | ||
version "1.1.4" | ||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" | ||
|
@@ -2464,6 +2488,11 @@ jackspeak@^2.3.5: | |
optionalDependencies: | ||
"@pkgjs/parseargs" "^0.11.0" | ||
|
||
"js-tokens@^3.0.0 || ^4.0.0": | ||
version "4.0.0" | ||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" | ||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== | ||
|
||
[email protected], js-yaml@^4.1.0: | ||
version "4.1.0" | ||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" | ||
|
@@ -2602,6 +2631,13 @@ [email protected]: | |
chalk "^4.1.0" | ||
is-unicode-supported "^0.1.0" | ||
|
||
loose-envify@^1.1.0: | ||
version "1.4.0" | ||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" | ||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== | ||
dependencies: | ||
js-tokens "^3.0.0 || ^4.0.0" | ||
|
||
loupe@^2.3.6: | ||
version "2.3.7" | ||
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" | ||
|
@@ -2621,6 +2657,13 @@ lru-cache@^6.0.0: | |
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" | ||
integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== | ||
|
||
magic-string@^0.30.3: | ||
version "0.30.9" | ||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.9.tgz#8927ae21bfdd856310e07a1bc8dd5e73cb6c251d" | ||
integrity sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw== | ||
dependencies: | ||
"@jridgewell/sourcemap-codec" "^1.4.15" | ||
|
||
make-dir@^4.0.0: | ||
version "4.0.0" | ||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" | ||
|
@@ -3036,6 +3079,21 @@ range-parser@~1.2.1: | |
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" | ||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== | ||
|
||
react-dom@^18.2.0: | ||
version "18.2.0" | ||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" | ||
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== | ||
dependencies: | ||
loose-envify "^1.1.0" | ||
scheduler "^0.23.0" | ||
|
||
react@^18.2.0: | ||
version "18.2.0" | ||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" | ||
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== | ||
dependencies: | ||
loose-envify "^1.1.0" | ||
|
||
readable-stream@~2.3.6: | ||
version "2.3.8" | ||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" | ||
|
@@ -3221,6 +3279,13 @@ saxes@^6.0.0: | |
dependencies: | ||
xmlchars "^2.2.0" | ||
|
||
scheduler@^0.23.0: | ||
version "0.23.0" | ||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" | ||
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== | ||
dependencies: | ||
loose-envify "^1.1.0" | ||
|
||
section-matter@^1.0.0: | ||
version "1.0.0" | ||
resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" | ||
|