简体   繁体   中英

Javascript widget : Check availability of jQuery and jQuery UI

I need to develop a Javascript Widget (almost finished), and by integrating it into the first site I found a few issues. My Widget needs to load a few libraries (jquery, jquery ui, mustache, ...); it is performed by injecting new script tags into the site with this function:

loadFile: function (filename, filetype) {
    if (filetype == "js") { //if filename is a external JavaScript file
        var fileref = document.createElement('script')
        fileref.setAttribute("type", "text/javascript")
        fileref.setAttribute("src", filename)
    } else if (filetype == "css") { //if filename is an external CSS file
        var fileref = document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("type", "text/css")
        fileref.setAttribute("href", filename)
    }
    if (typeof fileref != "undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref)
}

Is this good practice? The problem now comes from the fact that the hosting page of the widget might already have jquery and jquery-ui loaded. What can I do about it without having to change my code to much? I already found this page which describes a solution for jquery. But what about jQuery-ui? I currently have the problem, that my datepickers do not work, as the site already contains datepickers and jquery-ui. Can I change my widget so that my loaded javascript files do not interfear with the including site? And also make it possible to have two instances of the widget on the same site? For the css stuff I already have a solution by creating a diff with a specific Id around the widget content and use that Id in all Css selectors.

So my main concern is about loading my libraries, having them all available in the right version. My widget should not have any impact on the hosting site and vice versa. I might include jquery, but the site might use the $ for anything else.

I already thought about using Basket Js to perform the javascript loading, but this does not solve the injection issue.

Is there a nice way to include all my libraries into my widget.js without loading external resources? So that i can use § for my internal jquery? This must be a general solution working with all types of JS libraries.

I also found this but it only works with jQuery and not other libraries.

Any best practices for such a solution?

Best practice: keep the widget simple.

Instead of including autoloading functionality, simply specify the requirements and allow the implementing clients to include the correct dependencies:

This widget requires:

+ jQuery 1.9+
+ jQuery UI 1.10.4+

By performing a check for jQuery when your widget is run, you can fail fast and report back to the developer implementing the widget that a dependency is messing:

if (!window.jQuery) {
    throw new Error('The widget requires jQuery, please check http://widget/docs');
}

Convenience packages

Build tools such as Grunt can be used to to automatically put together "convenience" bundles that include the other libraries. I would provide this as an alternative, as clients may wish to avoid this pattern. Browsers can used cached copies of popular libraries, even across sites, if the client uses a CDN. For example jQuery has a jQuery CDN .

Closures for aliasing

A closure can be used to keep the widgets variables out of the global namespace, it can also be used to alias jQuery to $ even though $ may mean something entirely different to the rest of the page:

(function ($) {

    // Widget

}) (window.jQuery)

RequireJS

RequireJS can help by organising page dependencies:

define(['jquery-ui'], function($) {

    // Widget

});

This will mean that the implementing clients will need to use RequireJS , one alternative is to provide this as another alternative and have it built from the main source. With larger projects, using RequireJS to keep components small and separate is a really useful pattern, if you went down this route it is possible to build a RequireJS package into a package that can be used without the client having to include RequireJS by including the Almond shim .

Bower

Bower can also be used to register your widget and specify your dependencies so that implementing clients can grab your widget and all the dependencies they need by running a simple install command:

bower install my-widget

Conclusion

Even by just implementing the top two suggestions it will make your widget lightweight and easy to work with. Say a developer just adds the widget to the page, they will hit an error telling them that there are missing dependencies and to consult the documentation where they can find out exactly what they need to get it working.

Version compatibility is a problem and there is no simple outright fix as far as I am aware, the latter two tools can really help to minimise the problem. Example, say you have two widgets that require fundamentally different and incompatible versions of a library, have no knowledge of each other, by design. Simply the host page has to do a lot to get both widgets working together, or one widget has to be upgraded to use the latest version of the library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM