Skip to content

Site: deduplicate the CodeSandbox JS/TS sandbox define-API payload in index.jsx #4465

Closed

Description

@jadelike-wine

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

  1. github-actions commented on Nov 8, 2026

    @github-actions
    Contributor

    👋 @jadelike-wine,感谢给 TDesign 提出了 issue。
    请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。

  2. jadelike-wine commented on Nov 11, 2026

    @jadelike-wine
    ContributorAuthor

    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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions