Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
abstractalgo opened this issue Feb 4, 2024 · 3 comments

Comments

@abstractalgo
Copy link

abstractalgo commented Feb 4, 2024

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:

  • have Next skip parsing of typescript module:
    /** @type {import('next').NextConfig} */
    module.exports = {
      webpack: (config, options) => {
        config.module.noParse = [
          require.resolve("typescript/lib/typescript.js"),
          // require.resolve("./node_modules/typescript/lib/typescript.js"),
        ];
        return config;
      },
    };
    
  • use transpilePackages: ["typescript"] in next.config.js
  • started editing @valtown/codemirror-ts to not include any imports from typescript, and while that seems to help avoid the issue, it's not a scalable solution
  • tried the non-worker version, but the same error appears

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

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<WorkerShape | null>(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 (
    <CodeMirror
      value={value}
      height="200px"
      extensions={[
        javascript({ jsx: true, typescript: true }),
        tsFacetWorker.of({ worker, path: "index.ts" }),
        // tsSyncWorker(),
        // tsLinterWorker(),
        // autocompletion({
        //   override: [tsAutocompleteWorker()],
        // }),
        // tsHoverWorker(),
      ]}
      onChange={(value, _viewUpdate) => onChange(value)}
      onKeyDown={(e) => {
        if (e.key === "Enter") {
          e.preventDefault();
        }
      }}
      basicSetup={{
        lineNumbers: false,
        foldGutter: false,
        allowMultipleSelections: true,
        tabSize: 2,
      }}
    />
  );
};

Worker

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
Copy link
Member

tmcw commented Feb 4, 2024

Looks like this is an upstream bug in Webpack+TypeScript and there's a thread on the TypeScript repo: microsoft/TypeScript#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 abstractalgo changed the title Error: Critical dependency: the request of a dependency is an expression NextJS - Error: Critical dependency: the request of a dependency is an expression Feb 10, 2024
@abstractalgo abstractalgo changed the title NextJS - Error: Critical dependency: the request of a dependency is an expression Error: Critical dependency: the request of a dependency is an expression (NextJS/Webpack) Feb 10, 2024
@abstractalgo
Copy link
Author

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
Copy link
Member

tmcw commented Feb 12, 2024

👍 Hopefully this is resolved upstream!

@tmcw tmcw closed this as completed Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants