-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Refactor JavaScript mixins module #25587
Refactor JavaScript mixins module #25587
Conversation
Hi @krzksz. Thank you for your contribution
For more details, please, review the Magento Contributor Guide documentation. |
Exciting stuff! And getting rid of Traveling at the moment so sending this over to our performance team to give a first round of reviews. Thanks for the hard work on this! |
@magento run all tests |
4d11d0f
to
6f45eaa
Compare
6f45eaa
to
7961f8a
Compare
7961f8a
to
540b134
Compare
We are all green 🥳 However, now that I figured out how to write and run frontend unit tests locally, maybe it would be worth it to add some for mixins module? |
a162a4e
to
e922964
Compare
e922964
to
8eb66b5
Compare
Some smallunit tests would definitely be nice, but I'd hope we already have some e2e tests covering us so I wouldn't say it's critical. |
All of my work here is done I think, please post your feedback if any additional changes are needed. |
@DrewML I actually added some unit tests, so we are on the safe side 🤗 |
@omiroshnichenko unfortunately, only members of the maintainers team are allowed to assign developers to the pull request |
Hi @krzksz, thank you for your contribution! |
Hi @krzksz , is this fix applied in magento 2.3.4 version? in magento 2.3.4 release notes i cant find it. |
Hi @krzksz, will you backport this fix to 2.3-develop? Or I can do it if you do not mind. |
I have no idea how to even do it so you have the green light 😁
|
@krzksz Sorry, backport means just creating a PR with your fix to 2.3-develop 😁 |
I know, the issue is there is no 2.3-develop anymore. I'll ask other maintainers how to proceed here. |
I contacted Magento team and they are already working on a backport to 2.3 🤗 |
Yeah, I talked to them. I cherry picked your commits to 2.3-develop. I tested it with advanced bundling and with baler js bundling either. |
@gwharton Can you add a conditional breakpoint for |
Yes, turns out to be this module. https://github.com/swissup/module-stickyfill It is when this file is processed. view/frontend/web/js/stickyfill.js In function defContext.defQueue.shift, queueItem[1] is null. It is null in the GlobalDefaultQueue. The old version seemed to handle this ok. |
I verified that it is indeed an issue with modules defined in CommonJS format. I'll prepare PR that addresses this regression shortly. |
Hey @gwharton sorry for confusion but I have debugged the issue thoroughly and it is indeed the module's issue. The problem is that it defines itself using define(Stickyfill); and |
Is there any reason why this patch hasn't been included in the 2.3.4 or 2.3.5-p1 releases? |
Because: - [the PR](magento/magento2#25587) for the fix has been merged and released in Magento 2.3.6 (?) - [this repo](https://github.com/integer-net/magento2-requirejs-bundling) also says no patches are needed since Magento 2.3.6
Description (*)
This refactor started as an attempt to fix the fact that mixins were not loaded and applied for bundled modules when using advanced bundling technique. During the process I decided to dive a bit deeper and see if it is possible to improve the way Magento extends RequireJS functionality.
Bundling bug
First of all, after a lot of investigation I found that the only way for the plugin to retrieve true modules' paths no matter if they are bundled or not, is to prepare a separate context which excludes any bundles configuration.
Leaking of
arguments
In the previous implementation, functions like
applyMixins
,load
and overwrittendefine
were directly passing down specialarguments
object, which is considered a bad practice as it may leads to performance degradation and memory leaks so I refactored it away.Usage of
require.eval
Overwritten
define
method usedrequire.exec
which calls unsafe and poor-performingeval
to be used.I understand why this approach was used, the problem is that original RequireJS's
define
is able to append additional dependencies by analysing module's source code which happens here for example for bootstrap.js.Indeed, pushing the transformed item to a private
globalDefQueue
doesn't leave much hope for intercepting it in any other way but then I had a breakthrough. Instead of processing dependency names when they are added to the queue, we can do the same when they get transferred fromglobalDefQueue
to default context'sdefQueue
(which we have direct access to) and shifted from it by wrapping theshift
method. All of this happens before any of the dependencies are actually loaded so thre is no performance degradation or delay in requests involved. No more eval, another win.Wrapping global
require
anddefine
Solving the above point made it possible for me to actually get rid of overwriting global
define
function. Additionally, by wrapping default context'srequire
method, which always gets the parameters in normalized order and shape I was able to remove a lot of code that recreated original logic in order to retain compatibility with all RequireJS features.Fixed Issues (if relevant)
Manual testing scenarios (*)
Questions or comments
To be honest, I hoped that it would be possible to completely remove the need for plugin itself somehow while retaining it's functionality but I haven't figure out the way yet. That said, I'm very happy with the results of a few weeks worth of evenings and digging into RequireJS internals and the most important goal was achieved.
Contribution checklist (*)