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
Normalize property accessors for es6 namespaces and chained member/call expressions #17218
Comments
@vankop would you be able to point out which specific areas should be covered to achieve this? You worked a little bit in this area. |
hm.. not sure what to suggest. It affects parser api in sensitive part, if we would like to change this. So basically what webpack does here: lets give an example For each chain member => if it is computed If all members are static analyzable by webpack ( evaluated or computed=false ) it calls
So what you need is to change hook api :
Another option:
However, I have a question why it is an issue? with mangling enabled in webpack all chain members that are exports will be mangled, if member is a part of module object, like in your example, will it even work on module level? maybe it works when modules are concatenated? |
RE: why is this an issue. Mangling just mangles the imported object and not any chaining thereafter. Which is good, because it doesn't rewrite or control the other side of the code where the chained objects are created so mangling any further would break code at runtime. RE: concatenation. We can't rely on concatenation as (a) it is an option the user can choose to disable, and (b) there are plenty of cases that cause concatenation bail-out even when it is enabled. Webpack 4 was able to work with the Closure Compiler for excellent minification. Webpack 5 has broken that, and if our team is to move to Webpack 5 then we need to get this functionality restored. The core issue is that the chain elements following Webpack doesn't even consistently rewrite elements. In the case of optional chaining, Webpack currently bails out and stops rewriting the expression at that point. My guess is that this was done because the goal was to rewrite at least the imported object reference, and it is easy to detect and use this optional point because it is guaranteed that there are no nested module or imported objects referenced in an optional way. What I'm looking for is to have Webpack determine the actual point of the imported object in the expression and stop rewriting there so it at most rewrites the imported object reference. I don't think that |
In case of optional chaining webpack always bailouts, so in example bellow: 1 export {a..d}; 2.js export * as a from "1";
export * as b from "11";
export * as c from "111";
export * as d from "1111"; 3.js export * as a from "2";
export * as b from "2";
export * as c from "222";
export * as d from "2222"; main.js import * as D from "3";
console.log(D.b?.a.a); // this is same as import D.b for webpack in this case tree-shaken will be only module 3 ( a,c,d exports are unused ), and everything else will be bundled as "used in unknown way" |
there is no way to do this on module level, thats why webpack need to preserve all computed=true and then use it for non-exports members in chain |
maybe there is another option when 3rd argument ( probably it is 4th since full expression always also provided ) in hook is where expression range of callMemberChain.call(importTag, currentExpression, ["b", "c", "d"], fullExpression, [10, 12, 14]) so in dependency webpack will have |
Ok, so that will give all of the possible ranges. When rewriting the expression, how to best determine the exports part of an expression and pick the correct range? |
you need to take a look in Dependency |
I mean, given the expression "a.b.c.d", how do I determine that |
Thanks for your explanations and help, @vankop. I was able to figure it out from there. |
Feature request
Currently webpack rewrites chained member and call expressions in dot notation.
e.g.,
generates
Some optimizing compilers such as the Google Closure Compiler
ADVANCED
mode and Terser withkeep_quoted
enabled have a problem with this rewrite. They use the quote notation as a way to say, "hands off" when it comes to minifying variable names so that external interfaces can be preserved. This leads to it seeing x["somevar"] and x.somevar as two different properties, such that x.somevar is minified and x["somevar"] is converted to x.somevar (shorter by one char but not minified). See the Closure docs for more.What is the expected behavior?
The expression after the imported object (obj1 in this case) should remain untouched. That is,
What is motivation or use case for adding/changing the behavior?
Get webpack 5 to generate output compatible with the Google Closure Compiler.
How should this be implemented in your opinion?
When
HarmonyImportDependencyParserPlugin.js
constructsHarmonyImportSpecifierDependency
objects, it cannot know which parts of the member/call chain are the modules/imports and which parts are not. One option is for it to track and store all possibilities and their expression ranges, then choose which to use later in theFlagDependencyUsagePlugin
when webpack has knowledge about all imports and exports.Are you willing to work on this yourself?
Yes. I've created a failing-test PR (#17203) for now.
The text was updated successfully, but these errors were encountered: