-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Fails to resolve browser substitutions when mapping keys have no file extension #740
Comments
Further investigation seems to show that updating mapping as follows resolves the problem: "browser": {
"src/listener.js": "./src/listener.browser.js"
} However most other tools seem to work without requiring |
Addresses issue evanw/esbuild#740
Addresses issue with evanw/esbuild/issues/740
Ah, sorry about that. I wasn't aware of this edge case. Unfortunately the only documentation about how Here is some more specificity on how this feature works in Webpack (the de facto "specification" for this feature). I'm adding this information here for my own benefit and potentially for the benefit of others who come across this issue in the future. I believe these test cases show that you actually have to run the substitution twice, once before path resolution and once after path resolution: Case 1:
|
The de facto spec/implementation for this feature is browserify, not webpack. Every path, LHS and RHS, is fully reified using the node module resolution algorithm before doing any lookups. in other words, yes, you have to run the substitution/normalization multiple times. |
When I said that, I meant that Webpack is currently the most-used implementation of this feature (via npmtrends.com): In my opinion it would be better if esbuild works like Webpack instead of like Browserify if there's a divergence in behavior, since people are more likely to expect esbuild to work like Webpack. Here's an example of behavior divergence. If you provide the following substitution in {
"browser": {
"./foo/bar": "./foo_bar.js"
}
} and then import the path |
Webpack is the newcomer, usage aside, and whatever browserify does is the source of truth. If webpack doesn’t do it, it’s a bug in webpack. If a bug is filed on webpack, I’ll be happy to push them to fix it - it’s surely an oversight. |
It would be great to have this field actually fully specified and to push for the behavior to be consistent across bundlers. However, that seems like a semi-big project and I don't currently have the desire to do that myself. It could be cool if someone else wants to take on that task though. For whoever does want to take this on: The level of detail needed for the specification to be useful to implementers is something more like node's resolve algorithm specification than the current specification for the The behavior divergence I mentioned previously seems like a bug in Browserify to me, not a bug in Webpack. There is nothing actually at the path Edit: I filed this behavior divergence as a Browserify bug here: browserify/browserify#1994. |
Even if the file extension issue is fixed, the package mentioned in the original issue still doesn't work because it's also missing the leading @ljharb I'll give you an opportunity to pursue this with Webpack and/or Browserify if you'd like. So I will hold off on making this change in esbuild for the moment. However, if this is ends up remaining unresolved, I am currently thinking about changing esbuild to match Webpack's behavior here. |
The leading ./ is a long-time webpack bug in main, and simply isn’t required by node or browserify - so i assume there’s a similar bug with the browser field. |
ftr the package I’m representing here is https://github.com/es-shims/globalThis which works just fine with both webpack and browserify, and has a leading ./ |
Ok, I gave up and made some tests after all: https://github.com/evanw/package-json-browser-tests. Each test works in one of the bundlers, but there is no bundler that works with all of the tests. This is a mess. I assume a good end state is for esbuild to support the union of all of the behaviors of all of the other bundlers, so packages using this feature might break in other bundlers but they won't break in esbuild. |
Indeed, the lack of such tests in the first place has caused a lot of deviation. Thanks for making this; hopefully it can be used to bring all bundlers into compliance with the same feature set (or make it clear which things aren’t valid, like a number of the webpack-only ones). |
I am running into issue with package libp2p-websockets@0.15.0 which has
browser
field with following override:And a following line in
src/index.js
(which is also what is set asmain
):I would expect that bundling
src/index.js
would produce a bundle wheresrc/listener.js
is substituted forsrc/listener.browser.js
, however instead it fails (on esbuild@0.8.39):The text was updated successfully, but these errors were encountered: