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
fix: minified versionLt did not match the original function #11271
Conversation
|
For maintainers only:
|
I signed the CLA with the email it defaulted to (my personal email), but the commit was under my work email. Will that cause issue with the CLA check? |
Yes |
@snitin315 do you know how I fix it? It doesn't let me change the email address now. I could force push the commit with a different author email (I think)? |
Preempting the testing thing, I went ahead and tried to write something to test the runtime code. I've managed to get this working: describe("versionLt", () => {
const cases = [
"1 < 2",
"99 < 100",
// ... more cases
];
for (const c of cases) {
const parts = c.split(" < ");
const a = parts[0];
const b = parts[1];
const runtimeFunction = versionLtRuntimeCode({
basicFunction(args, body) {
return `(${args}) => {\n${body.join('\n')}\n}`;
}
});
const versionLtRuntime = eval(`(function (...args) { ${runtimeFunction}; return versionLt(...args); })`)
it(c, () => {
expect(versionLt(a, a)).toBe(false);
expect(versionLt(b, b)).toBe(false);
expect(versionLt(a, b)).toBe(true);
expect(versionLt(b, a)).toBe(false);
});
it(`${c} (runtime)`, () => {
expect(versionLtRuntime(a, a)).toBe(false);
expect(versionLtRuntime(b, b)).toBe(false);
expect(versionLtRuntime(a, b)).toBe(true);
expect(versionLtRuntime(b, a)).toBe(false);
});
}
}); Obviously using If you want these, I can add them to the PR, otherwise I'm happy to leave it untested. I think ultimately it would be awesome if the minified versions could be generated from the original instead of hand rolled, but that's a bit beyond my understanding of this codebase at this point. |
Yes you can force push. |
Hmm this really bother me. I throught this could happen and we would need some kind of linting step to verify that it's minimized correctly, but I have never implemented that. Thanks for pointing out that issue and I'll take it as opportunity to implement a linting step that does the minimizing and validates it. |
@sokra, just to clarify, are you saying you won't take this change and pursue a better fix or will you take this for now (if I fix the CLA issue and/or add the test above) and work towards the better fix in time? |
d129ada
to
c421803
Compare
c421803
to
f3688df
Compare
I had some spare time tonight, so I tried to write a thing to minify the original functions when building the templates so that it could never get out of sync. I ended up with: const { minify } = require('terser');
const makeMinified = (runtimeTemplate, fn, args) => {
const minifiedFn = minify(`const fn = ${fn.toString()}`, { mangle: { reserved: args } }).code;
const fnBody = minifiedFn.replace(`const fn=(${args.join(",")})=>{`, "").slice(0, -2);
return `var ${fn.name} = ${runtimeTemplate.basicFunction(args.join(", "), [
"// see webpack/lib/util/semver.js for original code",
fnBody
])}`;
}; The could then be called like: const versionLt = (a, b) => {
// ...
};
/* eslint-enable eqeqeq */
exports.versionLt = versionLt;
exports.versionLtRuntimeCode = runtimeTemplate => makeMinified(runtimeTemplate, versionLt, ["a", "b"]); This worked for that tests I previously posted, but as soon as I tried to apply it to I'm done for the night, but let me know if this idea has legs and I'll try to expand upon it in the morning. |
@sokra It looks like your commit is doing something similar to what I tried, only better and more complete but at build time instead of runtime. |
95236c6
to
675c8e8
Compare
verify runtime code in CI
675c8e8
to
6e71413
Compare
@sokra For what it's worth, I continued to pluck away at building the minified version at runtime, mostly or my own learning, and not have all of them producing minified output that passes the same tests the original versions do. The trick came from your change to move const { minify } = require('terser');
const makeMinified = (runtimeTemplate, fn, args) => {
const minifiedFn = minify(`const fn = ${fn.toString()}`, { mangle: { reserved: args } }).code;
const fnBody = minifiedFn.replace(`const fn=${args.length === 1 ? args[0] : `(${args.join(",")})`}=>{`, "").slice(0, -2);
return `var ${fn.name} = ${runtimeTemplate.basicFunction(args.join(", "), [
"// see webpack/lib/util/semver.js for original code",
fnBody
])}`;
};
// original functions...
exports.parseVersionRuntimeCode = runtimeTemplate => makeMinified(runtimeTemplate, parseVersion, ["str"]);
exports.versionLtRuntimeCode = runtimeTemplate => makeMinified(runtimeTemplate, versionLt, ["a", "b"]);
exports.rangeToStringRuntimeCode = runtimeTemplate => makeMinified(runtimeTemplate, rangeToString, ["range"]);
exports.satisfyRuntimeCode = runtimeTemplate => makeMinified(runtimeTemplate, satisfy, ["range", "version"]); Out of curiosity, do you feel like the build time approach you are taking has any major benefits over runtime generation? Are you interested in the tests I have that construct and evaluate the runtime versions to run the test cases against? I can add them on top of your commit after you get the build green if you want them. |
Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon. |
Yes tests are always good. Maybe in a separate PR as I want to publish this bugfix as soon as possible. I did go for the lint time approach because I didn't want to introduce terser as non-dev dependency and also save the time for spinning up terser and minimizing during webpack runtime. So mostly a performance choice. |
That makes sense. I'll put together a PR for the tests soon. |
Today |
I found an issue with module federation and the
strictVersion
option ofshared
packages. I have detailed my findings here, but the short version is the minifiedversionLt
function is not comparing semver version correctly, but when using the original version in NodeJS, it does.My investigation found that the minified version did not match the original function, so this PR is to correct that.
What kind of change does this PR introduce?
Bug Fix
Did you add tests for your changes?
No. There are already tests around the versionLt function, but the minified templates do not have any tests run against them. If this is an issue, please advise how you want them tested and I can look into it.
Does this PR introduce a breaking change?
No.
What needs to be documented once your changes are merged?
Nothing should need to be added.