Wrapping JavaScript libraries to allow multiple versions without conflicts - javascript

Background
We currently use jQuery to dynamically add third-party JavaScript libraries to our main index.html file at runtime (this is extremely simplified, but should help in understanding). Once they're added, the browser handles downloading them.
I'm wondering if there is there a way via some JavaScript library (or homegrown way) to dynamically modularize or wrap the third-party JavaScript libraries so that two versions of the same library can be loaded without conflicts and can be referenced independently?
For example:
Version A of 'underscore.js' could be referenced as:
versionA._.noop()
Version B of 'underscore.js' could be referenced as:
versionB._.noop()
Thus allowing both versions of 'underscore.js' to be available, but not conflict with each other?

Related

How to find out about loaded d3.js extensions and their versions at runtime?

As is customary with JavaScript libraries, the global root object supplied by d3.js has a self-identification attribute that returns (and thus, outputs, when called in the console) the version of the used library. In this case, it is
d3.version
Now, since version 4.0, d3.js is modular in that plenty of functionality built on top of the core features are placed in separate libraries, which have their own release cycles.
Now, I'm wondering whether I can also find out the version of, say, an extension such as d3-selection-multi that is currently loaded in my JavaScript environment. Is there a separate root object for every such extension with a version field of its own, or is that information (preferrably even a list of all loaded extensions?) provided somewhere in the d3 root object?
No, there is no way of detecting a module's version at runtime. D3's modules do not expose a version property like the bundle does nor does the bundle include any information about the included modules.

Can Javascript functionality be broken by overlapping scripts?

I'm currently working on an EJS webpage for a single module. In this framework, a set of default scripts are included for all modules, as well as a set of module-specific scripts. I can't change what is included.
I'm having issues getting a certain Highchart to be generated. Long story short, the common scripts included a Highchart library located at the framework's common library path. The module itself included a script to another Highchart library located at the module's local 3rd party library path. The name of these two scripts are different - I'm unable to tell if they are the same version whatsoever.
I'm in the process of troubleshooting but that's not the main point of this question. What I want to know is whether the existence of two different scripts of the same library being included in the same HTML page would cause problems?
It totally depends on the library, and specially, what else is executed between the first and second time the library is being initialized.
Short answer is yes, it is very likely to cause problems.

Polymer and working with external JavaScript Libraries

With Shadow DOM, I can easily use external CSS frameworks like bootstrap nicely and it will only apply to my scope which is nice (example here).
However, this doesn't apply to JavaScript libraries as far as I know. If I, for example, need to work with jQuery on my web component, I basically make it available for entire page. What is the recommend way to work with external JavaScript libraries with Polymer? How should I handle cases where my web component (which is distributed through bower) needs one version of foo.js and the consumer needs another?
There is no JavaScript encapsulation solutions I know of.
Check if js encapsulation solutions exist, e.g. check zonejs and alternatives.
You may do it yourself but this will require you to devote some time to it. E.g. I've encapsulated Babel with with statement as shown here (not tested).

Using a Helper in a Vendor - CakePHP

In my CakePHP app, I am defining a Wizard vendor that outputs the HTML for a multistep Wizard type plugin, along with its relevant Javascript code. I'm wanting to use the JsHelper so that I can buffer my code to the bottom of the page.
Everything else is working, including my Javascript code if I just output it directly with the HTML. I just can't quite figure out how to use the JsHelper. Do I use a App:Uses or App:Import statement? When using it in a View, I can just define it on the controller level, but that doesn't work here.
$this->Js->buffer("
$('.mws-wizard').wizard({
buttonContainerClass: 'mws-button-row',
orientation: '$orientation',
forwardOnly: $forwardOnly
});
");
If you are developing this 'vendor' package yourself, you should not develop it as a 'vendor', but as a plugin.
The vendor folders are meant for including third-party libraries that are not developed with CakePHP in mind (for example to use parts of the Zend Framework in your application).
From the manual:
Note: Loading vendors usually means you are loading packages that do not follow conventions. For most vendor packages using App::import() is recommended.
Create a plugin not a vendor
To develop re-usable code that can be used with different projects/applications, develop your code as a Plugin. Plugins are basically 'mini CakePHP applications'. Classes from a plugin can be used inside your application and vice-versa; a plugin can use CakePHP helpers the same way as you use them in your application.
See Creating Your Own Plugins
Regarding the JsHelper
Contrary to the comment placed by Sam Delaney, your usage of the JsHelper looks fine to me. Adding some script to the Js buffer to output it in the layout seems useful. Just don't try to use it for extended blocks of JavaScript; that should be put in external .js files.
I do recommend to write the JavaScript code yourself and not have the JsHelper generate the code for you (e.g. Don't use $this->Js->get('#foo')->event('click', $eventCode);). This may be personal, but IMO this makes it harder to track/debug your JavaScript and isn't any more readable than just $('#foo').click('event code');
I've personally never found any use for the JavaScript helper in CakePHP as if you're not careful, you end with getting <script> tags littering your markup, which sometimes makes it quite difficult to debug. From what you describe, you have the JavaScript aggregated and appended at the bottom of your HTML so it isn't as bad as the situation I highlight previously.
Is it not possible to relocate all your JavaScript to .js files to encapsulate all the function for your wizard plugin/vendor? If you could do this, it would be in keeping with MVC principles where you could logically separate the view markup and presentation logic.

MVC Bundles vs Javascript modules

As a ASP.NET MVC developer, I am trying to wrap my head around JavaScript AMD modules and libraries like RequireJS.
What is the relationship between ASP.NET MVC ScriptBundles and RequireJS?
In a large site with lots of JavaScript, should I be using both? Or one of them?
Should I integrate RequireJS with Bundles using IBundleTransform?
I wouldn't see using the two of these together. With Bundles you would have all your JavaScript loaded, ideally into just one or two bundles, on your layout controller. In production it would be optimized (combining into one file, minimised, cached and compressed etc).
RequireJS the way I see some of it is if you are being more granular about what JS is loaded and then you can use it's terse syntax to ensure a certain file is loaded before invoking some of that file's JavaScript.
I would recommend using Bundles since you are working with asp.net-mvc. They are pretty to use and work very well. I had used a similar pre mvc4 framework called Combres which was similar and this approach works very well for apps I think. It may be different for read only web sites.

Categories