Skip to content
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

Store the noconflict aliases #204

Open
rajasegar opened this issue Jan 18, 2021 · 6 comments · May be fixed by #205
Open

Store the noconflict aliases #204

rajasegar opened this issue Jan 18, 2021 · 6 comments · May be fixed by #205

Comments

@rajasegar
Copy link

Related to ember-cli/ember-resolver#629
We need to store the noconflict aliases within the global loader object, so that other libraries in the Ember ecosystem like ember-resolver can be able to use the aliased objects like define, require and requirejs instead of the default ones.

@simonihmig
Copy link

@rajasegar I tried to use your current work here (both your ember-resolver PR and #205 - through yarn link as it requires that prepublish build) to make an app coexist with a parent page that loads a lot of other JS, including AMD module based stuff, which causes both the Ember app and the 3rd party stuff to break miserably...

However I failed to make it work. Do you have this successfully working already?

The thing I fail with is how to properly put the code that calls loader.noConflict() at the right place. Unfortunately that seems not quite straightforward (#139). So what I have done so far is to put that code into my apps vendor folder and import it from ember-cli-build.js.

My understanding is - given that we still have all of vendor.js and app.js referencing the global define() (without taking any aliasing into account) - that we can only call noConflict() at the very end of all our app's code, right?

So with using app.import('vendor/loader-noconflict.js') I get my noConflict() call into vendor.js, however (even though I don't have set prepend: true) this does not put it at the end of the bundle (as some addon code comes thereafter). And so I can see that all modules define()ed before my noConflict() are ok, but expectedly all modules defined thereafter are throwing as define is undefined then.

But again, even putting it at the end of vendor.js would not be enough, as app.js also has a ton of define() calls that cannot be used anymore after noConflict().

So how is this actually supposed to work in a regular Ember app? Halp! 😀

@rajasegar-c
Copy link

@simonihmig here is the sample repo
https://github.com/rajasegar/multi-ember-app

@simonihmig
Copy link

Oh, thanks for the super quick response! Looking at your (built and minified) app code, it seems you are calling noConflict() in your app/app.js, right?

This does make sure that you are calling noConflict() after all app code as been evaluated before, which was what I was reasoning about above.

What I am still unsure about: does this guarantee to have no unexpected side effects on any 3rd party code? So let's assume I want to embed an Ember app into some 3rd party (server rendered) HTML page with lots of other JS. So you would have something like this:

<script type="text/javascript" src="/assets/vendor.js"></script>
<script type="text/javascript" src="/assets/my-embedded-app.js"></script>

<script type="text/javascript" src="/cms/some/other/3rdparty.js"></script>

With this, the browser would guarantee the evaluation order of these scripts, so 3rdparty.js would only be evaluated after my-embedded-app.js, but not necessarily after it has run (to the point where app/app.js is constructed). So at the time 3rdparty.js's first own define or require is seen by the browser, we might not have called noConflict() yet AFAICT, right?

That's why I thought it has to be put at the end of app.js, but basically at the root level, not within some code that is only executed asynchronously (e.g. after DOMContentLoaded).

Does that make sense?

@rajasegar
Copy link
Author

Yes @simonihmig that makes sense.

@simonihmig
Copy link

simonihmig commented Feb 18, 2021

So far, I have failed to make this work. One reason is quite specific to my app, and out of scope of the general case. But two other issues blocked this furthermore:

FWIW, the only way I finally got my app to coexist with other AMD-based scripts on the same page was to use ember-derequire (after some local updates that still need to get integrated upstream) and ditching ember-classic-decorators...

@rajasegar
Copy link
Author

I knew about ember-data but not ember-classic-decorators, I will check out ember-derequire

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants