ts-plus / typescript

Apache License 2.0
37 stars 5 forks source link

VSCode and tsc very slow when using external tsplusTypes #252

Closed patroza closed 1 year ago

patroza commented 1 year ago

Initializing language features in editor, as well as compiling, takes very very long on my projects since using external tsPlusTypes definitions. I mean I do have a lot of errors atm as im converting, but the process is very painful with such slow load times

Additionally I noticed the code that scans for the tsplusTypes is called multiple times for me during build for example. Not sure if it maybe needs caching. Will see if I can find out why

Perhaps also related: https://github.com/ts-plus/typescript/issues/248

Using these https://github.com/tim-smart/effect-rpc/tree/main/packages/router/vendor by @tim-smart coming out of https://github.com/tim-smart/tsplus-gen

patroza commented 1 year ago

I've fixed the performance issue with 3 caches, but the last one seems to have made the most difference. (initialize caches outside the Parser definition)

1: const tsPlusTypeCache = {}

      for (const resolvedPath of resolvedPaths) {
        const json = resolvedPath in tsPlusTypeCache ? tsPlusTypeCache[resolvedPath] : (() => { const text = sys.readFile(resolvedPath); if (text) { const json = JSON.parse(text); tsPlusTypeCache[resolvedPath] = json; return json}})()
        if (json) {

2: const resolvedPathsCache = {}

    if (options.configFilePath) {
      const resolvedPaths = getResolvedPaths(options)
      if (resolvedPaths.length === 0) {
        return;
      }
  function getResolvedPaths(options) {
    if (options.configFilePath in resolvedPathsCache) { return resolvedPathsCache[options.configFilePath] }
    let resolvedPaths = [];
      if (options.tsPlusTypes) {
        for (const path of options.tsPlusTypes) {
          if (pathIsRelative(path)) {
            resolvedPaths.push(resolvePath(options.configFilePath.split("/").slice(0, -1).join("/"), path));
          } else {
            const resolvedModule = resolveModuleName(path, options.configFilePath, options, sys).resolvedModule;
            if (resolvedModule) {
              resolvedPaths.push(resolvedModule.resolvedFileName);
              break;
            }
          }
        }
      }
      const packagePath = removeExtension(options.configFilePath.split("node_modules").slice(-1)[0].substring(1), ".d.ts");
      if (packagePath) {
        let packageName;
        if (packagePath.startsWith("@")) {
          packageName = packagePath.split(directorySeparator).slice(0, 2).join(directorySeparator);
        } else {
          packageName = packagePath.split(directorySeparator).slice(0, 1)[0];
        }
        const resolvedPackageJson = resolvePackageNameToPackageJson(packageName, options.configFilePath, options, sys, void 0);
        if (resolvedPackageJson) {
          const packageJsonText = sys.readFile(resolvePath(resolvedPackageJson.packageDirectory, "package.json"));
          if (packageJsonText) {
            const packageJson = JSON.parse(packageJsonText);
            if (packageJson.tsPlusTypes) {
              for (const path of toArray(packageJson.tsPlusTypes)) {
                resolvedPaths.push(resolvePath(resolvedPackageJson.packageDirectory, path));
              }
            }
          }
        }
        if (packagePath.startsWith("@")) {
          packageName = mangleScopedPackageName(packagePath.split(directorySeparator).slice(0, 2).join(directorySeparator));
        } else {
          packageName = packagePath.split(directorySeparator).slice(0, 1)[0];
        }
        const { resolvedModule } = resolveModuleName(`@tsplus-types/${packageName}`, options.configFilePath, { ...options, resolveJsonModule: true }, sys);
        if (resolvedModule) {
          resolvedPaths.push(resolvedModule.resolvedFileName);
        }
      }
      resolvedPathsCache[options.configFilePath] = resolvedPaths
      return resolvedPaths
  }

3:

const resolvedModuleCache = {}

const resolvedModule = key in resolvedModuleCache ? resolvedModuleCache[key] : (resolvedModuleCache[key] = resolveModuleName(moduleName, options.configFilePath, options, sys).resolvedModule);
patroza commented 1 year ago

The diff to my patch is here: https://github.com/effect-ts-app/libs/pull/21/files#diff-2d8242e8fed0e717f1e83478a154f8c6401df0ae6efd8e5e6b4103cadf318c0f

patroza commented 1 year ago

@0x706b this seems to work well now, thanks!