@mandujs/core 0.54.30 → 0.54.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
18
18
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import path from "node:path";
|
|
21
|
+
import { pathToFileURL } from "node:url";
|
|
21
22
|
import {
|
|
22
23
|
_testOnly_generateJsxDevRuntimeShimSource,
|
|
23
24
|
_testOnly_generateJsxRuntimeShimSource,
|
|
@@ -32,10 +33,9 @@ describe("JSX runtime shim sources (issues #322 / #323)", () => {
|
|
|
32
33
|
// the import statement, not comment mentions of the path.)
|
|
33
34
|
expect(source).not.toMatch(/from\s*['"]react\/jsx-dev-runtime['"]/);
|
|
34
35
|
|
|
35
|
-
// Correct: jsxDEV +
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
);
|
|
36
|
+
// Correct: jsxDEV (+ jsx/jsxs fallback inputs) come from bare 'react'
|
|
37
|
+
// (→ _react.js). Import includes jsxDEV and resolves from "react".
|
|
38
|
+
expect(source).toMatch(/import\s*\{[^}]*\bjsxDEV\b[^}]*\}\s*from\s*['"]react['"]/);
|
|
39
39
|
|
|
40
40
|
// Shim still re-exports what the import map expects.
|
|
41
41
|
expect(source).toContain("export { jsxDEV, Fragment }");
|
|
@@ -83,4 +83,58 @@ describe("JSX runtime shim sources (issues #322 / #323)", () => {
|
|
|
83
83
|
await rm(dir, { recursive: true, force: true });
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
|
+
|
|
87
|
+
// #323 re-regression (0.54.30): a SOURCE/static check passed but at RUNTIME
|
|
88
|
+
// `_react.js`'s jsxDEV was `undefined` (jsxDEV is a React dev-only export;
|
|
89
|
+
// a production-built _react.js drops it while keeping jsx/jsxs). The shim
|
|
90
|
+
// re-exported that undefined → "jsxDEV is not a function". Guard the VALUE:
|
|
91
|
+
// build the dev shim against a `react` stub whose jsxDEV is undefined (the
|
|
92
|
+
// exact failing condition) and assert the shim still exposes a callable
|
|
93
|
+
// jsxDEV via its jsx/jsxs fallback.
|
|
94
|
+
test("dev shim exposes a callable jsxDEV even when react.jsxDEV is undefined (runtime value)", async () => {
|
|
95
|
+
const dir = await mkdtemp(path.join(tmpdir(), "mandu-jsx-shim-rt-"));
|
|
96
|
+
try {
|
|
97
|
+
// Stub for bare 'react' = a production-built _react.js: jsx/jsxs are real
|
|
98
|
+
// functions, jsxDEV is missing.
|
|
99
|
+
const reactStub = path.join(dir, "react-stub.js");
|
|
100
|
+
await writeFile(
|
|
101
|
+
reactStub,
|
|
102
|
+
[
|
|
103
|
+
"export const jsx = (type) => ({ type, runtime: 'jsx' });",
|
|
104
|
+
"export const jsxs = (type) => ({ type, runtime: 'jsxs' });",
|
|
105
|
+
"export const Fragment = Symbol.for('react.fragment');",
|
|
106
|
+
"export const jsxDEV = undefined;",
|
|
107
|
+
].join("\n"),
|
|
108
|
+
"utf-8",
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Generate the real shim source, but resolve its bare `react` import to
|
|
112
|
+
// the stub so we can drive the undefined-jsxDEV condition.
|
|
113
|
+
const shimSource = _testOnly_generateJsxDevRuntimeShimSource().replace(
|
|
114
|
+
/from\s*['"]react['"]/g,
|
|
115
|
+
`from ${JSON.stringify(reactStub.replace(/\\/g, "/"))}`,
|
|
116
|
+
);
|
|
117
|
+
const shimSrc = path.join(dir, "_jsx-dev-runtime.src.js");
|
|
118
|
+
await writeFile(shimSrc, shimSource, "utf-8");
|
|
119
|
+
|
|
120
|
+
const result = await Bun.build({
|
|
121
|
+
entrypoints: [shimSrc],
|
|
122
|
+
target: "browser",
|
|
123
|
+
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
124
|
+
});
|
|
125
|
+
expect(result.success).toBe(true);
|
|
126
|
+
|
|
127
|
+
const outPath = path.join(dir, "_jsx-dev-runtime.built.js");
|
|
128
|
+
await writeFile(outPath, await result.outputs[0]!.text(), "utf-8");
|
|
129
|
+
const mod = await import(`${pathToFileURL(outPath).href}?t=${Date.now()}`);
|
|
130
|
+
|
|
131
|
+
// The whole point of #323's re-regression: jsxDEV must be CALLABLE.
|
|
132
|
+
expect(typeof mod.jsxDEV).toBe("function");
|
|
133
|
+
// Fallback routes static-children to jsxs, otherwise jsx.
|
|
134
|
+
expect(mod.jsxDEV("div", {}, undefined, false).runtime).toBe("jsx");
|
|
135
|
+
expect(mod.jsxDEV("div", {}, undefined, true).runtime).toBe("jsxs");
|
|
136
|
+
} finally {
|
|
137
|
+
await rm(dir, { recursive: true, force: true });
|
|
138
|
+
}
|
|
139
|
+
});
|
|
86
140
|
});
|
package/src/bundler/build.ts
CHANGED
|
@@ -660,12 +660,24 @@ function generateJsxDevRuntimeShimSource(): string {
|
|
|
660
660
|
* Development JSX 변환용
|
|
661
661
|
*
|
|
662
662
|
* #323: import map의 'react/jsx-dev-runtime'이 다시 이 셰임을 가리키므로
|
|
663
|
-
* 'react/jsx-dev-runtime'에서 import하면 순환 self-import가
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
663
|
+
* 'react/jsx-dev-runtime'에서 import하면 순환 self-import가 된다. 대신
|
|
664
|
+
* 'react'(→ _react.js, react 전체를 인라인하는 vendor 번들)에서 가져온다.
|
|
665
|
+
*
|
|
666
|
+
* #323 재발(0.54.30): jsxDEV는 React의 **dev 전용** export다. _react.js가
|
|
667
|
+
* production NODE_ENV로 번들되면 'react/jsx-dev-runtime'이 production 변형으로
|
|
668
|
+
* 해소되어 jsxDEV 값이 undefined가 된다(jsx/jsxs는 둘 다 존재). 그 결과 dev
|
|
669
|
+
* island가 'jsxDEV is not a function'으로 전멸했다. _react.js가 어떤 NODE_ENV로
|
|
670
|
+
* 빌드되든 안전하도록, jsxDEV가 함수가 아니면 jsx/jsxs로 폴백한다(dev 경고만
|
|
671
|
+
* 잃고 렌더는 정상). isStaticChildren일 때는 jsxs로 라우팅한다.
|
|
667
672
|
*/
|
|
668
|
-
import { jsxDEV, Fragment } from 'react';
|
|
673
|
+
import { jsx, jsxs, jsxDEV as __manduReactJsxDEV, Fragment } from 'react';
|
|
674
|
+
|
|
675
|
+
const jsxDEV =
|
|
676
|
+
typeof __manduReactJsxDEV === 'function'
|
|
677
|
+
? __manduReactJsxDEV
|
|
678
|
+
: function jsxDEV(type, config, key, isStaticChildren) {
|
|
679
|
+
return (isStaticChildren ? jsxs : jsx)(type, config, key);
|
|
680
|
+
};
|
|
669
681
|
|
|
670
682
|
// Named exports
|
|
671
683
|
export { jsxDEV, Fragment };
|