Skip to content

Commit 42b5b50

Browse files
committed
dynamicは不要なことがわかった
1 parent eadb2a9 commit 42b5b50

File tree

1 file changed

+50
-78
lines changed

1 file changed

+50
-78
lines changed

app/terminal/typescript/runtime.tsx

Lines changed: 50 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,24 @@ import {
1313
import { useEmbedContext } from "../embedContext";
1414
import { ReplOutput } from "../repl";
1515
import { RuntimeContext } from "../runtime";
16-
import dynamic from "next/dynamic";
1716

1817
export const compilerOptions: CompilerOptions = {};
1918

20-
type TSModules = {
21-
ts: typeof import("typescript");
22-
vfs: typeof import("@typescript/vfs");
23-
};
24-
interface ITypeScriptContext {
25-
modules: TSModules | null;
26-
setModules: (modules: TSModules) => void;
27-
tsEnv: VirtualTypeScriptEnvironment | null;
28-
}
29-
const TypeScriptContext = createContext<ITypeScriptContext>({
30-
modules: null,
31-
setModules: () => {},
32-
tsEnv: null,
33-
});
34-
const LazyInitTypeScript = dynamic(
35-
async () => {
36-
const ts = await import("typescript");
37-
const vfs = await import("@typescript/vfs");
38-
return function LazyInitTypeScript() {
39-
const { setModules } = useContext(TypeScriptContext);
40-
useEffect(() => {
41-
setModules({ ts, vfs });
42-
}, [setModules]);
43-
return null;
44-
};
45-
},
46-
{ ssr: false }
19+
const TypeScriptContext = createContext<VirtualTypeScriptEnvironment | null>(
20+
null
4721
);
4822
export function TypeScriptProvider({ children }: { children: ReactNode }) {
4923
const [tsEnv, setTSEnv] = useState<VirtualTypeScriptEnvironment | null>(null);
50-
const [modules, setModules] = useState<TSModules | null>(null);
5124

5225
useEffect(() => {
53-
if (modules !== null && tsEnv === null) {
54-
const { ts, vfs } = modules;
26+
// useEffectはサーバーサイドでは実行されないが、
27+
// typeof window !== "undefined" でガードしないとなぜかesbuildが"typescript"を
28+
// サーバーサイドでのインポート対象とみなしてしまう。
29+
if (tsEnv === null && typeof window !== "undefined") {
5530
const abortController = new AbortController();
5631
(async () => {
32+
const ts = await import("typescript");
33+
const vfs = await import("@typescript/vfs");
5734
const system = vfs.createSystem(new Map());
5835
const libFiles = vfs.knownLibFilesForCompilerOptions(
5936
compilerOptions,
@@ -90,81 +67,76 @@ export function TypeScriptProvider({ children }: { children: ReactNode }) {
9067
abortController.abort();
9168
};
9269
}
93-
}, [tsEnv, setTSEnv, modules]);
70+
}, [tsEnv, setTSEnv]);
9471
return (
95-
<TypeScriptContext.Provider value={{ tsEnv, modules, setModules }}>
96-
<LazyInitTypeScript />
72+
<TypeScriptContext.Provider value={tsEnv}>
9773
{children}
9874
</TypeScriptContext.Provider>
9975
);
10076
}
10177

10278
export function useTypeScript(jsEval: RuntimeContext): RuntimeContext {
103-
const { modules, tsEnv } = useContext(TypeScriptContext);
79+
const tsEnv = useContext(TypeScriptContext);
10480

10581
const { writeFile } = useEmbedContext();
10682
const runFiles = useCallback(
10783
async (filenames: string[], files: Record<string, string>) => {
108-
if (tsEnv === null || modules === null) {
84+
if (tsEnv === null || typeof window === "undefined") {
10985
return [
11086
{ type: "error" as const, message: "TypeScript is not ready yet." },
11187
];
112-
}
88+
} else {
89+
for (const [filename, content] of Object.entries(files)) {
90+
tsEnv.createFile(filename, content);
91+
}
11392

114-
for (const [filename, content] of Object.entries(files)) {
115-
tsEnv.createFile(filename, content);
116-
}
93+
const outputs: ReplOutput[] = [];
11794

118-
const outputs: ReplOutput[] = [];
95+
const ts = await import("typescript");
11996

120-
for (const diagnostic of tsEnv.languageService.getSyntacticDiagnostics(
121-
filenames[0]
122-
)) {
123-
outputs.push({
124-
type: "error",
125-
message: modules.ts.formatDiagnosticsWithColorAndContext(
126-
[diagnostic],
127-
{
97+
for (const diagnostic of tsEnv.languageService.getSyntacticDiagnostics(
98+
filenames[0]
99+
)) {
100+
outputs.push({
101+
type: "error",
102+
message: ts.formatDiagnosticsWithColorAndContext([diagnostic], {
128103
getCurrentDirectory: () => "",
129104
getCanonicalFileName: (f) => f,
130105
getNewLine: () => "\n",
131-
}
132-
),
133-
});
134-
}
106+
}),
107+
});
108+
}
135109

136-
for (const diagnostic of tsEnv.languageService.getSemanticDiagnostics(
137-
filenames[0]
138-
)) {
139-
outputs.push({
140-
type: "error",
141-
message: modules.ts.formatDiagnosticsWithColorAndContext(
142-
[diagnostic],
143-
{
110+
for (const diagnostic of tsEnv.languageService.getSemanticDiagnostics(
111+
filenames[0]
112+
)) {
113+
outputs.push({
114+
type: "error",
115+
message: ts.formatDiagnosticsWithColorAndContext([diagnostic], {
144116
getCurrentDirectory: () => "",
145117
getCanonicalFileName: (f) => f,
146118
getNewLine: () => "\n",
147-
}
148-
),
149-
});
150-
}
119+
}),
120+
});
121+
}
151122

152-
const emitOutput = tsEnv.languageService.getEmitOutput(filenames[0]);
153-
files = await writeFile(
154-
Object.fromEntries(
155-
emitOutput.outputFiles.map((of) => [of.name, of.text])
156-
)
157-
);
123+
const emitOutput = tsEnv.languageService.getEmitOutput(filenames[0]);
124+
files = await writeFile(
125+
Object.fromEntries(
126+
emitOutput.outputFiles.map((of) => [of.name, of.text])
127+
)
128+
);
158129

159-
console.log(emitOutput);
160-
const jsOutputs = jsEval.runFiles(
161-
[emitOutput.outputFiles[0].name],
162-
files
163-
);
130+
console.log(emitOutput);
131+
const jsOutputs = jsEval.runFiles(
132+
[emitOutput.outputFiles[0].name],
133+
files
134+
);
164135

165-
return outputs.concat(await jsOutputs);
136+
return outputs.concat(await jsOutputs);
137+
}
166138
},
167-
[modules, tsEnv, writeFile, jsEval]
139+
[tsEnv, writeFile, jsEval]
168140
);
169141
return {
170142
ready: tsEnv !== null,

0 commit comments

Comments
 (0)