diff --git a/platforms/cloudflare/create-vfs-twoslasher.mjs b/platforms/cloudflare/create-vfs-twoslasher.mjs deleted file mode 100644 index 264b18696ae86..0000000000000 --- a/platforms/cloudflare/create-vfs-twoslasher.mjs +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -/** - * Creates a Twoslash instance backed by a virtual filesystem for environments - * without real filesystem access (e.g. Cloudflare Workers). - * - * Uses a pre-built JSON map of TypeScript lib declarations and @types/node - * generated at build time by `scripts/twoslash-fsmap/index.mjs`. - */ -export async function createVfsTwoslasher() { - const { createTwoslasher } = await import('twoslash/core'); - const ts = (await import('typescript')).default; - const fsMapJson = ( - await import('./generated/twoslash-fsmap.json', { with: { type: 'json' } }) - ).default; - - const fsMap = new Map(Object.entries(fsMapJson)); - - return createTwoslasher({ - fsMap, - tsModule: ts, - vfsRoot: '/', - compilerOptions: { - moduleResolution: ts.ModuleResolutionKind.Bundler, - // Explicitly include @types/node so that the VFS resolves Node.js - // globals and `node:*` module imports from the bundled declarations. - types: ['node'], - }, - }); -} diff --git a/platforms/cloudflare/mdx.mjs b/platforms/cloudflare/mdx.mjs index 05f4aeadf0c07..0a74eb0b3b616 100644 --- a/platforms/cloudflare/mdx.mjs +++ b/platforms/cloudflare/mdx.mjs @@ -1,12 +1,8 @@ -import { createVfsTwoslasher } from './create-vfs-twoslasher.mjs'; - // Cloudflare workers can't load `shiki/wasm` via `WebAssembly.instantiate` with -// custom imports, so fall back to the JavaScript RegEx engine. Twoslash needs -// a VFS since there's no real filesystem at runtime; we provide one backed by -// a JSON map built at deploy time from the TypeScript lib declarations and -// `@types/node`. +// custom imports, so fall back to the JavaScript RegEx engine. Twoslash pulls +// Node.js filesystem modules into the Worker bundle during OpenNext page-data +// collection, so keep code highlighting enabled without Twoslash on Cloudflare. export const shikiOptions = { wasm: false, - twoslash: true, - twoslashOptions: { twoslasher: await createVfsTwoslasher() }, + twoslash: false, }; diff --git a/platforms/cloudflare/package.json b/platforms/cloudflare/package.json index b59aa461c71ed..b8ff7b233ca16 100644 --- a/platforms/cloudflare/package.json +++ b/platforms/cloudflare/package.json @@ -12,11 +12,8 @@ "directory": "platforms/cloudflare" }, "scripts": { - "prebuild:cloudflare": "node ./scripts/twoslash-fsmap/index.mjs", "build:cloudflare": "cross-env NODE_OPTIONS=--conditions=cloudflare pnpm --filter=@node-core/website exec opennextjs-cloudflare build --openNextConfigPath ../../platforms/cloudflare/open-next.config.ts --config ../../platforms/cloudflare/wrangler.jsonc", - "predeploy": "node ./scripts/twoslash-fsmap/index.mjs", "deploy": "cross-env NODE_OPTIONS=--conditions=cloudflare pnpm --filter=@node-core/website exec opennextjs-cloudflare deploy --openNextConfigPath ../../platforms/cloudflare/open-next.config.ts --config ../../platforms/cloudflare/wrangler.jsonc", - "predev": "node ./scripts/twoslash-fsmap/index.mjs", "dev": "pnpm --filter=@node-core/website exec wrangler dev --config ../../platforms/cloudflare/wrangler.jsonc", "playwright": "cross-env NODE_OPTIONS=--conditions=cloudflare pnpm --filter=@node-core/website playwright" }, @@ -24,8 +21,6 @@ "@flarelabs-net/wrangler-build-time-fs-assets-polyfilling": "^0.0.1", "@opennextjs/cloudflare": "^1.19.3", "@sentry/cloudflare": "^10.49.0", - "@typescript/vfs": "^1.6.4", - "twoslash": "^0.3.8", "wrangler": "^4.77.0", "typescript": "catalog:" }, diff --git a/platforms/cloudflare/scripts/twoslash-fsmap/generate.mjs b/platforms/cloudflare/scripts/twoslash-fsmap/generate.mjs deleted file mode 100644 index d1fdf784d740d..0000000000000 --- a/platforms/cloudflare/scripts/twoslash-fsmap/generate.mjs +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; - -import { readdirSync, readFileSync } from 'node:fs'; -import { createRequire } from 'node:module'; -import { join, resolve } from 'node:path'; - -import { createDefaultMapFromNodeModules } from '@typescript/vfs'; -import ts from 'typescript'; - -const require = createRequire(import.meta.url); - -/** - * Recursively collects all `.d.ts` files from a directory into the fsMap. - * - * @param {Map} fsMap The map to populate - * @param {string} dir The directory to walk - * @param {string} virtualPrefix The virtual path prefix (e.g., "/node_modules/@types/node") - * @param {string} baseDir The base directory for computing relative paths - */ -function collectDtsFiles(fsMap, dir, virtualPrefix, baseDir) { - const entries = readdirSync(dir, { withFileTypes: true }).sort((a, b) => - a.name.localeCompare(b.name) - ); - - for (const entry of entries) { - const fullPath = join(dir, entry.name); - - if (entry.isDirectory()) { - collectDtsFiles(fsMap, fullPath, virtualPrefix, baseDir); - } else if (entry.isFile() && /\.d\.([^.]+\.)?[cm]?ts$/i.test(entry.name)) { - const relativePath = fullPath.slice(baseDir.length).replace(/\\/g, '/'); - const virtualPath = `${virtualPrefix}${relativePath}`; - - fsMap.set(virtualPath, readFileSync(fullPath, 'utf8')); - } - } -} - -/** - * Generates a virtual filesystem map containing all TypeScript library - * declaration files and `@types/node` declarations needed for Twoslash - * to run without real filesystem access (e.g., on Cloudflare Workers). - * - * @returns {Map} A map of virtual paths to file contents - */ -export default function generateTwoslashFsMap() { - // 1. Collect TypeScript lib .d.ts files using @typescript/vfs - // This returns a Map keyed as "/lib.es5.d.ts", "/lib.dom.d.ts", etc. - const fsMap = createDefaultMapFromNodeModules({}, ts); - - // 2. Collect @types/node .d.ts files - // These are keyed as "/node_modules/@types/node/index.d.ts", etc. - const typesNodeDir = resolve( - require.resolve('@types/node/package.json'), - '..' - ); - - collectDtsFiles( - fsMap, - typesNodeDir, - '/node_modules/@types/node', - typesNodeDir - ); - - return fsMap; -} diff --git a/platforms/cloudflare/scripts/twoslash-fsmap/index.mjs b/platforms/cloudflare/scripts/twoslash-fsmap/index.mjs deleted file mode 100644 index bfc812024f278..0000000000000 --- a/platforms/cloudflare/scripts/twoslash-fsmap/index.mjs +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -import { mkdirSync, writeFileSync } from 'node:fs'; - -import generateTwoslashFsMap from './generate.mjs'; - -const fsMap = generateTwoslashFsMap(); - -const outputPath = new URL( - '../../generated/twoslash-fsmap.json', - import.meta.url -); - -mkdirSync(new URL('.', outputPath), { recursive: true }); -writeFileSync(outputPath, JSON.stringify(Object.fromEntries(fsMap)), 'utf8'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc459c4ab260a..1eb1601ef7b04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -583,18 +583,12 @@ importers: '@sentry/cloudflare': specifier: ^10.49.0 version: 10.49.0(@cloudflare/workers-types@4.20260422.1) - '@typescript/vfs': - specifier: ^1.6.4 - version: 1.6.4(typescript@5.9.3) next: specifier: 'catalog:' version: 16.3.0-canary.30(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: specifier: 'catalog:' version: 19.2.6 - twoslash: - specifier: ^0.3.8 - version: 0.3.8(typescript@5.9.3) typescript: specifier: 'catalog:' version: 5.9.3