val-town / codemirror-ts

lint, hover, and autocomplete extensions for CodeMirror + TypeScript
https://val-town.github.io/codemirror-ts/
ISC License
105 stars 6 forks source link

Error: Critical dependency: the request of a dependency is an expression (NextJS/Webpack) #18

Closed abstractalgo closed 4 months ago

abstractalgo commented 4 months ago

I'm building a NextJS app (14.0.4) and trying to use @valtown/codemirror-ts, but I get the following errors:

# this is from the worker
./node_modules/@typescript/vfs/dist/vfs.esm.js
Critical dependency: the request of a dependency is an expression

# this is from React code
./node_modules/typescript/lib/typescript.js
Critical dependency: the request of a dependency is an expression

I tried:

It really seems like it doesn't like importing typescript, so I was wondering if you had any tips to overcome this issue.

React code

```ts import CodeMirror from "@uiw/react-codemirror"; import { javascript } from "@codemirror/lang-javascript"; import { useState, type FC, useEffect } from "react"; import { tsFacetWorker } from "@valtown/codemirror-ts"; import { type WorkerShape } from "@valtown/codemirror-ts/worker"; import * as Comlink from "comlink"; export const CodeMirrorEditor: FC<{ value?: string; onChange: (value: string) => void; }> = ({ value, onChange }) => { const [worker, setWorker] = useState(null); useEffect(() => { (async () => { try { const innerWorker = new Worker( new URL("../src/worker.ts", import.meta.url), { type: "module", } ); const worker = Comlink.wrap(innerWorker) as WorkerShape; await worker.initialize(); setWorker(worker); } catch (e) { console.error(e); } })(); }, []); if (!worker) { return null; } return ( onChange(value)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); } }} basicSetup={{ lineNumbers: false, foldGutter: false, allowMultipleSelections: true, tabSize: 2, }} /> ); }; ```

Worker

```ts import { createDefaultMapFromCDN, createSystem, createVirtualTypeScriptEnvironment, } from "@typescript/vfs"; import * as ts from "typescript"; import * as Comlink from "comlink"; import { createWorker } from "@valtown/codemirror-ts/worker"; Comlink.expose( createWorker(async function () { const fsMap = await createDefaultMapFromCDN( { target: ts.ScriptTarget.ES2022 }, ts.version, false, ts ); const system = createSystem(fsMap); const compilerOpts = {}; return createVirtualTypeScriptEnvironment(system, [], ts, compilerOpts); }) ); ```

tmcw commented 4 months ago

Looks like this is an upstream bug in Webpack+TypeScript and there's a thread on the TypeScript repo: https://github.com/microsoft/TypeScript/issues/39436

It looks like there are some proposed solutions there, plus a PR that was merged that should fix it in recent TypeScript releases.

abstractalgo commented 4 months ago

Many StackBlitz/CodeSandbox examples use a similar @typescript/vfs setup, but bundle with Vite or Remix, which don't have this issue -- this indeed seems like a NextJS/Webpack-specific issue. I'll consider alternative setups for the time being (feel free to resolve this Github issue). Thanks for your help!

tmcw commented 4 months ago

👍 Hopefully this is resolved upstream!