tsconfig-paths-webpack-plugin icon indicating copy to clipboard operation
tsconfig-paths-webpack-plugin copied to clipboard

Extensions are hardcoded

Open jonaskello opened this issue 6 years ago • 5 comments

See here. Should use the extensions from webpack.config.js somehow?

jonaskello avatar Dec 08 '17 16:12 jonaskello

This is still relevant. The hardcode is now here:

https://github.com/dividab/tsconfig-paths-webpack-plugin/blob/f7099a708385e7e762ed257bcb1788b535a37107/src/options.ts#L63

They should be taken from webpack config's resolve.extensions by default, otherwise aliased imports to *.js produce unpredicted import failures while relative imports to the same files work fine. Example:

import 'alias/foo' // not found
import 'alias/foo.js' // found - but leads to ugly code
import '../../alias-dest/foo' // also found

This is also what #28 is about.

IlyaSemenov avatar Sep 28 '18 17:09 IlyaSemenov

Apparently it's not that easy. TsconfigPathsPlugin is a plugin for enhanced-resolver and doesn't get access to webpack config options (only to the resolver which is decoupled from webpack). The resolver object is given the list of extensions when constructed, but does not save them, it only converts them to a bunch of AppendPlugin's in ResolverFactory.js. So in theory it's possible to recover the list of extensions in TsconfigPathsPlugin by parsing the other resolver plugins, but it means introducing a dependency on third party undocumented internals.

Another way is to pass undefined for extensions, then tsconfig-paths will use require.extensions, see match-path-async.ts. However, webpack doesn't sync require.extensions with its config.resolve.extensions so that would help with importing *.js but would break importing *.ts. 🤷‍♀️

So the intermediate solution for now would be to at least document that TsconfigPathsPlugin should always be constructed as TsconfigPathsPlugin({ extensions: config.resolve.extensions }).

IlyaSemenov avatar Sep 29 '18 06:09 IlyaSemenov

I also started to wonder why didn't you just push a few enhanced-resolve AliasPlugin's based on parsed tsconfig paths instead of everything that's taking place? Similar to how the default resolver factory alias option works... That would be the native solution to the problem.

IlyaSemenov avatar Sep 29 '18 06:09 IlyaSemenov

Apparently it's not that easy. TsconfigPathsPlugin is a plugin for enhanced-resolver and doesn't get access to webpack config options

Yes, that is why it was not done from the beginning :-). Perhaps you can create an issue at the webpack repo to give resolver plugins access to the extensions.

I also started to wonder why didn't you just push a few enhanced-resolve AliasPlugin's

The work on this plugin was originally based on how the corresponding plugin in awsome-typescript-loader worked, but using the tsconfig-paths package instead. Each path does not resolve to exactly one place but an array of places. However it might be possible to do it with alias plugins, you are welcome to make a branch and try it out. I do wish that we had a lot more tests that could verify alternative approaches. Anyway, any contributions that simplifies the codebase while maintaining full functionality are definitely welcome.

jonaskello avatar Sep 29 '18 12:09 jonaskello

It works well witn Storybook for *.mdx files:

new TsconfigPathsPlugin({extensions: config.resolve.extensions});

monolithed avatar Nov 13 '20 23:11 monolithed