Skip to content

Expose configuration hook for custom module resolution #18896

Description

Following on from #6012 and #5039, it'd be nice to have the ability to add TypeScript to projects with heterogeneous module resolution/packaging systems and have typechecking work.

The paths and baseUrl configuration options get us a long way, but they don't deal well with module loaders that are less widely used, frequently changing, or that allow for complex module resolution rules. Letting the user entirely outsource all module resolution concerns using the configuration would allow type checking to work regardless of the user's preference of npm, bower, requirejs, browserify, jspm, webpack, etc.

A simple approach might be to have a tsconfig option for a parametrized command line invocation (similar to npm scripts) that is able to resolve modules. Each package manager can distribute a tool that implements module resolution according to its own needs, which the users can install and point to in their tsconfig.json.

Exactly how extensive the API needs to be is up for debate. It could be something as simple as a function that maps requested module names to file system paths, or a more abstract implementation of something like System from here, which could open up more interesting use cases (e.g. "virtual" modules built using code generation, or F# style type providers).

Activity

  1. RyanCavanaugh commented on Oct 2, 2017

    @RyanCavanaugh
    Member

    Note that this is already an option for non-tsc environments because the host object given to the compiler exposes resolveModuleNames which hosts may implement to their liking.

    I'm not sure there's anyone who would want this ability who isn't already loading TS through some more advanced build pipeline.

  2. masaeedu commented on Oct 2, 2017

    @masaeedu
    ContributorAuthor

    Ryan Cavanaugh (@RyanCavanaugh) I want to continue using VS Code as a regular editor, but also be able to use JSPM/ bower/custom webpack without doing a lot of fiddling with paths in tsconfig.

    It would also be nice if I could more generally hook into the module resolution pipeline without having to implement a full language server and wrapping extension.

  3. aluanhaddad commented on Oct 2, 2017

    @aluanhaddad
    Contributor

    I think this could become quite flexible and workable without having too many options. Currently typescript uses a fallback strategy when resolving modules and that forgiving behavior doesn't need to change as a result of this feature.

    For example, let's say I'm using moment and_bootstrap_ in my application.

    I can't provide a path mapping for bootstrap because of how its declaration file references jQuery's. so maybe I have installed that declaration using npm but I have moment installed with JSPM and moment comes with its own type declaration and I that is the one I want to use and I can today just manually. so when TypeScript resolves moment, I could via this feature suggest 'jspm_packages/npm/[email protected]" as a possible path resolution. However, in the case of bootstrap, the default rules could still be applied.

  4. davidsk commented on Oct 14, 2017

    @davidsk

    I've also been trying to cobble together a working vscode / typescript / jspm project and eventually came to a similar conclusion as this issue describes.

    My thoughts were a new compilerOption which would identify a custom resolver module that would return an array of objects, mapping containingFiles / moduleNames keys to module locations.

    [
      "*": {
        "module1": "path/to/module1",
        "module2": "path/to/module2"  
      },
      "module1": {
        "module2": "different/path/to/module3"
      }
    ]
    

    When should such a function be called? It could be called early on in the process and cached but if design time support is required then the map would need updated dynamically. I suspect Typescript already has a mechanism to do this.

  5. DanielRosenwasser commented on Oct 15, 2017

    @DanielRosenwasser
    Member

    I believe this could also solve some issues with remote/network file systems at larger organizations (e.g. #16426).

  6. guybedford commented on Jan 12, 2018

    @guybedford
    Contributor

    I'd be very interested in a hook here for jspm resolver support.

  7. SupernaviX commented on Feb 8, 2018

    @SupernaviX

    Asad Saeeduddin (@masaeedu) I played around a bit with modifying ts.sys to use"virtual modules"/type providers. I'd be very interested if this API was flexible enough to support virtual modules in a more general way.

  8. arcanis commented on Oct 21, 2018

    @arcanis
    Contributor

    Just saw this issue - I'd be quite interested as well to have such a hook. Would allow me to start making experiments to integrate PnP with Typescript 🙂

  9. darthtrevino commented on Nov 1, 2018

    @darthtrevino
    Member

    Would a new "moduleResolution" option make sense for this? Maybe something like yarnpnp? I'd like to have the basic tsc toolchain work yarn plug-n-play

  10. webcarrot commented on Nov 22, 2018

    @webcarrot

    Hi. I propose some solution in #28624 that allow to provide in compilerOptions custom file resolution function (from node module or file). It works fine with tsc and language server.

  11. lukeapage commented on Dec 27, 2018

    @lukeapage

    The current situations makes this a no-go for us to use typescript.
    Even the flow functionality of allowing a regex replace to the filename would allow us to use our multi-app module resolution. customResolution would be perfect.

  12. NullVoxPopuli commented on Apr 24, 2019

    @NullVoxPopuli

    Any progress on this? Just had to convert a project in a monorepo to yarn-pnp to resolve a dependency problem, and because I now have no node_modules in that project, tsserver does not find any of my dependencies :(

  13. masaeedu commented on May 27, 2019

    @masaeedu
    ContributorAuthor

    I was thinking about it a little bit, and given sufficient metadata about the types in the codebase, you could also use this as a sort of primitive typeclass system. As an example:

    type eq<a> = { equals: (x: a, y: a) => boolean }
    
    type arrEq = <a>(a: eq<a>) => eq<a[]>
    const arrEq: arrEq = a => {
      const equals = (xs, ys) => all(zipWith(a.equals, xs, ys))
      return { equals }
    }
    
    const strEq: eq<string> = { equals: (x, y) => x === y }
    
    type t = eq<string[]>
    const arrStr: t = require("<resolve>")
    // Here we introspect over the types of things in the codebase, and
    // produce a module that exports `arrEq(strEq)`
    
    arrStr.equals(["foo", "bar"], ["foo", "bar"]) // => true

    Of course, this is a rather nutty idea, and maybe not the best use case for this sort of feature, but as Jurassic Park teaches us, if you can, you should. What could go wrong?

  14. shrinktofit commented on Jan 10, 2020

    @shrinktofit

    Any move on this?

  15. moccaplusplus commented on Apr 18, 2020

    @moccaplusplus

    Ryan Cavanaugh (@RyanCavanaugh) This could actually solve my feature request #31703
    I could just write custom resolution strategy plugin to address my needs.

  16. drdevelop commented on May 14, 2020

    @drdevelop

    Asad Saeeduddin (@masaeedu) may be you can attempt library of typescript-module-alias

  17. shrinktofit commented on Oct 16, 2020

    @shrinktofit

    Any move on this?

    Any? 🔢

  18. rdsedmundo commented on Mar 24, 2021

    @rdsedmundo

    It would be really great to have this on TS. Webpack and Babel both support writing custom resolvers. ESLint also has, through eslint-plugin-import.

    There's a similar issue with some good insights on its usefulness: typescript-eslint/typescript-eslint#2771 (I actually think it should've been here as it's not typescript-eslint job to solve this but tsc).

  19. muzuiget commented on May 27, 2021

    @muzuiget

    Year 2021, still looking forward on this.

    This document https://www.typescriptlang.org/docs/handbook/module-resolution.html#module-resolution-strategies now is some complex, why not just give a hook function for user to do the resolve.

  20. JasonKleban commented on Apr 29, 2022

    @JasonKleban

    Would it be the ideal solution for nodejs to stabilize the loaders api, given that typescript's module resolution mimics node's module resolution algorithm?

  21. piecyk commented on May 18, 2022

    @piecyk

    This would allow to type check one project by types from others, for example i have a common-ui package that has a peerDependencies for react17 and 18, and devDependencies is set to react18.

    I would like to import it in app17 and typecheck common-ui with react17, now it's not possible as the node resolution kiks in and picks types from common-ui node_modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions