feat: allow configuration of the typescript-compiler (#66241)

This commit is contained in:
Oliver Eyton-Williams
2026-03-05 05:18:18 +01:00
committed by GitHub
parent c94fe2d40e
commit 2972485a87
5 changed files with 27 additions and 18 deletions
@@ -16,10 +16,15 @@ export class Compiler {
this.tsvfs = tsvfs;
}
async setup(opts?: { useNodeModules: boolean }) {
async setup(opts?: { useNodeModules?: boolean; compilerOptions?: unknown }) {
const ts = this.ts;
const tsvfs = this.tsvfs;
const parsedOptions = ts.convertCompilerOptionsFromJson(
opts?.compilerOptions ?? {},
'/'
);
const compilerOptions: CompilerOptions = {
target: ts.ScriptTarget.ES2024,
module: ts.ModuleKind.Preserve, // Babel is handling module transformation, so TS should leave them alone.
@@ -28,7 +33,8 @@ export class Compiler {
// sync with TypeScript over time. It was last synced with TypeScript
// 3.8.0-rc."
jsx: ts.JsxEmit.Preserve, // Babel will handle JSX,
allowUmdGlobalAccess: true // Necessary because React is loaded via a UMD script.
allowUmdGlobalAccess: true, // Necessary because React is loaded via a UMD script.
...parsedOptions.options
};
const fsMap = opts?.useNodeModules
@@ -1,3 +1,4 @@
import type { CompilerOptions } from 'typescript';
import { Compiler } from './modules/typescript-compiler';
// Most of the ts types are only a guideline. This is because we're not bundling
@@ -23,9 +24,10 @@ interface TSCompiledMessage {
error: string;
}
interface CheckIsReadyRequestEvent extends MessageEvent {
interface SetupEvent extends MessageEvent {
data: {
type: 'check-is-ready';
type: 'setup';
compilerOptions?: CompilerOptions;
};
}
@@ -59,12 +61,10 @@ function importTS(version: string) {
cachedVersion = version;
}
ctx.onmessage = (
e: TSCompileEvent | CheckIsReadyRequestEvent | CancelEvent
) => {
ctx.onmessage = (e: TSCompileEvent | SetupEvent | CancelEvent) => {
const { data, ports } = e;
if (data.type === 'check-is-ready') {
void handleCheckIsReadyRequest(ports[0]);
if (data.type === 'setup') {
void handleSetupRequest(data, ports[0]);
} else if (data.type === 'cancel') {
handleCancelRequest(data);
} else {
@@ -75,15 +75,16 @@ ctx.onmessage = (
importTS(TS_VERSION);
const compiler = new Compiler(ts, tsvfs);
const isSetup = compiler.setup();
// This lets the client know that there is nothing to cancel.
function handleCancelRequest({ value }: { value: number }) {
postMessage({ type: 'is-alive', text: value });
}
async function handleCheckIsReadyRequest(port: MessagePort) {
await isSetup;
async function handleSetupRequest(data: SetupEvent['data'], port: MessagePort) {
await compiler.setup({
compilerOptions: data.compilerOptions
});
// We freeze this to prevent learners from getting the worker into a weird
// state.
Object.freeze(self);