Repository navigation
Description
Problem
packages/tdesign-react/site/src/components/codesandbox/index.jsx issues the CodeSandbox define request through two fully duplicated fetch blocks — one for TypeScript demos and one for JS demos — that differ only in file extensions (src/main.tsx vs src/main.jsx, src/demo.tsx vs src/demo.jsx, and the extra tsconfig.json for TS). Any future fix to the shared payload (manifest, index.html, styles, entry file) must be edited in two places and can silently drift apart.
Note: this issue is scoped to the index.jsx payload deduplication only; the separate ReactDOM.render -> createRoot template change in content.js is tracked elsewhere and is intentionally out of scope here.
Proposal
Extract a single shared code path that builds the file map (parameterized by the demo language for extensions and the conditional tsconfig.json) and posts it to https://codesandbox.io/api/v1/sandboxes/define?json=1, keeping identical filenames, identical shared files, and identical success behavior (opening https://codesandbox.io/s/<id>?file=/src/demo.<ext>).
Scope
Site only: packages/tdesign-react/site/src/components/codesandbox/index.jsx. No component API, type.ts, defaultProps.ts, or submodule changes.
Validation
Regression tests are pending — a node:test spec at packages/tdesign-react/site/test/codesandbox.test.mjs asserts a single define-API request path while preserving both JS and TS file sets; it currently fails on the duplicated baseline. Manual check: pnpm dev, open a component page, generate a JS and a TS demo sandbox and confirm identical payloads other than the language-specific files.
Executed reproduction
Baseline: 0701c679bd4608c5445ee7ce61d94b916c70e4da
{
"argv": [
"node",
"--test",
"packages/tdesign-react/site/test/codesandbox.test.mjs"
],
"exit_code": 1,
"output": "✖ CodeSandbox define API request is built once and shared for JS and TS demos (3.4059ms)\n✔ sandbox generation still supports both JS and TS demos (0.3662ms)\n✔ successful sandbox creation still opens the returned sandbox URL (0.1314ms)\nℹ tests 3\nℹ suites 0\nℹ pass 2\nℹ fail 1\nℹ cancelled 0\nℹ skipped 0\nℹ todo 0\nℹ duration_ms 128.971\n\n✖ failing tests:\n\ntest at packages\\tdesign-react\\site\\test\\codesandbox.test.mjs:15:1\n✖ CodeSandbox define API request is built once and shared for JS and TS demos (3.4059ms)\n AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\n \n 2 !== 1\n \n at TestContext.<anonymous> (file:///C:/Users/silver/Documents/github/oss-contributor/workspaces/Tencent--tdesign-react--hunt-2cafd23230c6/packages/tdesign-react/site/test/codesandbox.test.mjs:17:10)\n at Test.runInAsyncScope (node:async_hooks:226:14)\n at Test.run (node:internal/test_runner/test:1397:25)\n at Test.start (node:internal/test_runner/test:1257:17)\n at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {\n generatedMessage: true,\n code: 'ERR_ASSERTION',\n actual: 2,\n expected: 1,\n operator: 'strictEqual',\n diff: 'simple'\n }\n\n"
}
Regression test
New regression file: packages/tdesign-react/site/test/codesandbox.test.mjs
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import test from 'node:test';
const codesandboxDir = join(dirname(fileURLToPath(import.meta.url)), '../src/components/codesandbox');
const indexSource = readFileSync(join(codesandboxDir, 'index.jsx'), 'utf8');
// Regression: the CodeSandbox "define" request must be issued through a single
// shared code path. The baseline builds the whole fetch payload twice (once for
// `.tsx` demos, once for `.jsx` demos), so any template fix has to be edited in
// two places and can drift apart. On the unfixed source this assertion fails
// with `2 !== 1`.
test('CodeSandbox define API request is built once and shared for JS and TS demos', () => {
const occurrences = indexSource.match(/codesandbox\.io\/api\/v1\/sandboxes\/define/g) ?? [];
assert.equal(occurrences.length, 1);
});
// Boundaries of the refactor: deduplicating the payload must not drop support
// for either demo language or change what the action does on success.
test('sandbox generation still supports both JS and TS demos', () => {
// Language detection still drives which file names are posted.
assert.match(indexSource, /currentLangIndex|isTypeScriptDemo/);
assert.match(indexSource, /tsx/);
assert.match(indexSource, /jsx/);
// TS demos keep their tsconfig; JS demos still omit it.
assert.match(indexSource, /tsconfig\.json/);
// Every variant still ships the shared manifest, page and styles.
assert.match(indexSource, /'package\.json'/);
assert.match(indexSource, /'public\/index\.html'/);
assert.match(indexSource, /'src\/index\.css'/);
});
test('successful sandbox creation still opens the returned sandbox URL', () => {
assert.match(indexSource, /window\.open\(`https:\/\/codesandbox\.io\/s\//);
});
AI-assisted contribution.
Our implementation
PR: #4467
Activity
github-actions commentedon Nov 8, 2026
👋 @jadelike-wine,感谢给 TDesign 提出了 issue。
请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。
jadelike-wine commentedon Nov 11, 2026
The duplicated CodeSandbox define-API payload in index.jsx was deduplicated and merged in #4467 (single shared request path; TS/JS file sets preserved). The separate ReactDOM.render -> createRoot template change in content.js was intentionally out of scope for this issue, so this issue is now complete and can be closed. Thanks for the review!