Skip to content

Add customModuleResolution / customModuleResolver to compilerOptions #28624

New issue

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

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

Already on GitHub? # to your account

Closed
5 tasks done
webcarrot opened this issue Nov 20, 2018 · 2 comments
Closed
5 tasks done

Add customModuleResolution / customModuleResolver to compilerOptions #28624

webcarrot opened this issue Nov 20, 2018 · 2 comments
Labels
Duplicate An existing issue was already created In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@webcarrot
Copy link

webcarrot commented Nov 20, 2018

Search Terms

module file resolution custom

Suggestion

Add customModuleResolution / customModuleResolver to compilerOptions. This option provide path or name to custom module resolver module/file that should provide function that could resolve modules/files in custom way.

Simple implementation / working example:
https://github.com/webcarrot/TypeScript/commit/97781d8cba76fb3e3b4e07c295af918e94ceed80

Use Cases

Anything that is related with files resolution and cannot be handled by setting compilerOptions.paths etc.

Examples

Postfixs for different run-time environments:

Files:

./a.browser.ts // implementation for browsers
./a.node.ts // implementation for node
./b.ts

b.ts file:

import { a } from "./a"; // resolve to a.node.ts for example

Example custom resolver implementation:

import * as Typescript from "typescript";
import { existsSync } from "fs";
import { join, dirname } from "path";

type ResolveOutput =
  | Typescript.ResolvedModuleWithFailedLookupLocations
  | undefined;

const POSTFIXS = ["node", "browser", "modern"];

const EXTENSIONS = [
  "d.ts",
  "ts",
  "tsx",
  "js",
  "jsx",
  "abc" // custom extensions work - but not to well
];

const EXTENSIONS_MAP: { [key: string]: Typescript.Extension } = {
  "d.ts": Typescript.Extension.Dts,
  ts: Typescript.Extension.Ts,
  tsx: Typescript.Extension.Tsx,
  js: Typescript.Extension.Js,
  jsx: Typescript.Extension.Jsx,
  abc: Typescript.Extension.Ts // hack abc as ts
};

const check = (
  path: string,
  postfix: string,
  extension: string
): ResolveOutput => {
  const resolvedFileName = `${path}.${postfix}.${extension}`;
  if (existsSync(resolvedFileName)) {
    return {
      resolvedModule: {
        resolvedFileName,
        isExternalLibraryImport: false,
        extension: EXTENSIONS_MAP[extension]
      }
    };
  }
  return undefined;
};

export default (
  moduleName: string,
  containingFile: string,
  compilerOptions: Typescript.CompilerOptions
): ResolveOutput => {
  if (
    moduleName.startsWith(".") &&
    containingFile.startsWith(join(compilerOptions.baseUrl, "src"))
  ) {
    const path = join(dirname(containingFile), moduleName);
    return POSTFIXS.reduce<ResolveOutput>(
      (out, postfix) =>
        out
          ? out
          : EXTENSIONS.reduce<ResolveOutput>(
              (out, extension) => (out ? out : check(path, postfix, extension)),
              undefined
            ),
      undefined
    );
  }
  return undefined;
};

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals. (?)

Contraindications

  • This feature is insecure in language server context. Probably some configuration flag for language server should be provided to enable this feature.
  • Nobody want feature like this? 😞
@weswigham
Copy link
Member

Related: #28289

Duplicates #18896

@weswigham weswigham added Suggestion An idea for TypeScript Duplicate An existing issue was already created In Discussion Not yet reached consensus labels Nov 20, 2018
@typescript-bot
Copy link
Collaborator

This issue has been marked as a duplicate and has seen no activity in the last day. It has been closed automatic house-keeping purposes.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Duplicate An existing issue was already created In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants