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
ESBuild resolves modules by using the TypeScript moduleSuffixes
per package instead of per bundle
#2395
Comments
You can override esbuild's choice of |
Right. Thanks for the pointer! That kind of works, but I imagine I would like to override only What is the use case for bundling files in a package using the |
The compilation model esbuild currently uses is designed to replace the workflow where you run TypeScript's documentation says this:
It looks like the TypeScript team is expecting you to explicitly pass a platform-specific |
I love that esbuild works that way, and it's amazing that one tool can deal with all the tiny details of all the tools it's replacing, but Imagine a shared npm package that implements a button with separate implementations for each platform. The developer sets up a default I don't think you need to deal with |
But by that argument, esbuild shouldn't respect The rationale for To be clear: I don't personally care about this either way. I don't use anything in Facebook's ecosystem myself. I'm just trying to figure out a consistent set of rules for how esbuild is put together. It sounds like you're saying that esbuild should not apply path remappings from I could potentially remove support for I also wonder what other tools do here. I could easily see Webpack doing this (having their own way of specifying path remappings). I haven't looked into this myself though. |
The path mapping is a local per package mapping, and doesn't have any of the problems that Platform Forking has where the canonical React Native bundler does the final global platform resolution. To support React Native style platform forking in Webpack you would use the resolve.extensions list. The React standard |
The
moduleSuffixes
feature of TypeScript is now being used for module resolution in ESBuild, but for a bundle this should be set once per whole bundle, and not locally per package.React Native has Platform Specific Extensions, which is used by its Metro Bundler to allow JavaScript modules to be forked per platform. So for example a
Button
module could have aButton.ios.jsx
implementation for iOS and aButton.android.jsx
for Android. The right fork (for exampleios
) is selected per bundle, so you choose the current platform for your bundle globally.In TypeScript this is now supported via the
moduleSuffixes
configuration. You can then set themoduleSuffixes
in a shared package'stsconfig.json
, and TypeScript will then type-check that package using the platform extensions in the order of themoduleSuffixes
list. This is though not shared outside that package. The order is only used as one arbitrary way to test a set of resolutions. If you want to type check for multiple platforms you would have to have multiple configuration files with its ownmoduleSuffixes
list and run TypeScript once per the platform you want to test.The problem is that ESBuild is using the per package
moduleSuffixes
when resolving module paths for the bundle. The correct way would be to ignoremoduleSuffixes
for bundling, and rather let the user set the resolution order with the per bundle ESBuildresolveExtensions
setting. For exampleresolveExtensions: [ ".ios.tsx", ".tsx", ".ios", ".ts", ".js", ".jsx" ],
.I'm not sure I can see a use for ESBuild to support
moduleSuffixes
at all, but at least it should be configurable as the usual way to set the resolution is once for all the code in your bundle.The text was updated successfully, but these errors were encountered: