ts-morph icon indicating copy to clipboard operation
ts-morph copied to clipboard

Make it easier to analyze Deno code

Open dsherret opened this issue 4 years ago • 3 comments

As pointed out at https://github.com/dsherret/ts-morph/issues/949#issuecomment-792288644, one important caveat to using ts-morph to analyze Deno code is that even though ts-morph runs in Deno, it cannot be used to analyze Deno code out of the box. Deno has a lot of custom Compiler API code to do what they do. For example, the TS compiler out of the box, doesn't know how to read module specifiers with an extension.

Deno's Module Resolution

  • [x] Add helper host
  • [ ] Look into module resolution caching (forget exactly what it is and I'm lazy to look it up at the moment)

Deno requires custom module resolution. This can be implemented by doing something like this as outlined in the custom module resolution docs:

const project = new Project({
    resolutionHost: (moduleResolutionHost, getCompilerOptions) => {
        return {
            resolveModuleNames: (moduleNames, containingFile) => {
                const compilerOptions = getCompilerOptions();
                const resolvedModules: ts.ResolvedModule[] = [];

                for (const moduleName of moduleNames.map(removeTsExtension)) {
                    const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost);
                    if (result.resolvedModule)
                        resolvedModules.push(result.resolvedModule);
                }

                return resolvedModules;
            },
        };

        function removeTsExtension(moduleName: string) {
            if (moduleName.slice(-3).toLowerCase() === ".ts")
                return moduleName.slice(0, -3);
            return moduleName;
        }
    },
});

That said, I've added a reusable host that makes this slightly easier, so you can do this:

import { ResolutionHosts } from "https://deno.land/x/[email protected]/mod.ts";

const project = new Project({
    resolutionHost: ResolutionHosts.deno,
});

I think there's stuff like resolution host caching and other things that's not being done properly yet here though, so just be aware that things here are subject to change, though they won't change much.

@deno-types

  • [ ] Investigate how @deno-types works

Deno allows specifying a declaration file for imports and exports. For example:

// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"
import React from "https://cdn.pika.dev/[email protected]";

Remote Modules

  • [ ] Need to be able to download and cache them... lots of work.

Other?

  • [ ] Investigate what else there is. Luckily Deno doesn't use too much magic, so I don't think it should be too hard.
  • [ ] Should there be a global isDeno: true or runtimeType: Runtimes.Deno or something like that to make this even easier?

dsherret avatar Mar 07 '21 14:03 dsherret

@dsherret - it might be possible to leverage the work by @lucacasonato with his esbuild plugin: https://github.com/lucacasonato/esbuild_deno_loader

spence avatar Nov 19 '23 06:11 spence