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

[ts-transform-paths] Error when using with transpileModule. #31

Open
IgorSzymanski opened this issue Apr 28, 2020 · 2 comments
Open

[ts-transform-paths] Error when using with transpileModule. #31

IgorSzymanski opened this issue Apr 28, 2020 · 2 comments

Comments

@IgorSzymanski
Copy link

IgorSzymanski commented Apr 28, 2020

When running an application using in ts-node with --transpile-only flag (or ts-node-dev) and ttypescript with ts-transform-paths plugin, the plugin doesn't seem to work.
I did some research and the reason is transpile-only of ts-node mode and ts-node-dev compile the code using transpileModule function of the main typescript library.

https://github.com/microsoft/TypeScript/blob/468ca9f87076db70aa7d0b037a73f5232b6834e6/src/services/transpile.ts#L26-L102

Now, ts-transform-paths gets info about paths from an object implementing the interface Program

transformationContext.getCompilerOptions()

Here is the interface:
https://github.com/microsoft/TypeScript/blob/167f954ec7cf456238cad4f2006fb330c53bba8e/src/compiler/types.ts#L3195-L3300

The transformationContext is created by TS itself, but when it's created inside transpileModule function, things get a bit weird...

(Here's the line where the Program instance is created).
https://github.com/microsoft/TypeScript/blob/167f954ec7cf456238cad4f2006fb330c53bba8e/src/services/transpile.ts#L90

        const program = createProgram([inputFileName], options, compilerHost);

Because the options that are passed to the factory are not exactly what's in tsconfig.json.
And here are the lines that are responsible for that:
https://github.com/microsoft/TypeScript/blob/167f954ec7cf456238cad4f2006fb330c53bba8e/src/services/transpile.ts#L32-L41

        const defaultOptions = getDefaultCompilerOptions();
        for (const key in defaultOptions) {
            if (hasProperty(defaultOptions, key) && options[key] === undefined) {
                options[key] = defaultOptions[key];
            }
        }


        for (const option of transpileOptionValueCompilerOptions) {
            options[option.name] = option.transpileOptionValue;
        }

What this fragment does is it takes this array:
https://github.com/microsoft/TypeScript/blob/167f954ec7cf456238cad4f2006fb330c53bba8e/src/compiler/commandLineParser.ts#L224-L1000
And replaces each property of tsconfig.json with the value of matching transpileOptionValue property, and in case of paths it's:

        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "paths",
            type: "object",
            affectsModuleResolution: true,
            isTSConfigOnly: true,
            category: Diagnostics.Module_Resolution_Options,
            description: Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl,
            transpileOptionValue: undefined
        },

undefined

So when ts-transform-paths tries to resolve paths in a transpileOnly mode, it cannot do so, because the config it gets in this mode using this

transformationContext.getCompilerOptions();

has paths set to undefined.

The summary is: getCompilerOptions() of a Program instance is not a reliable way of accessing info about paths, because the data is lost in transpileOnly mode. There should be another way to access such data, because they probably won't change the behaviour in typescript library, because they always consider such things intentional.

You can see the library failing in this repo:
https://github.com/IgorSzymanski/ts-transform-paths-bug-repro

Either run

yarn
yarn start:dev

or

yarn
yarn start:transpile

on the contrary:

yarn
yarn start:live

Will work just fine, because it's not using transpileOnly mode.

@bradennapier
Copy link

Would be great to get this working! I mentioned it in this issue on ts-node and there is some more context there as well.

@nonara
Copy link

nonara commented Aug 3, 2021

FYI - typescript-transform-paths now supports being used without a Program instance. It's now usable via ts-node --transpileOnly. I am currently in process of simplifying it to work via it's own register script

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

3 participants