Publishing a library that requires CSS with RequireJS - javascript

I publish a library called DataTables and I'm looking to improve how it works with package managers for the next set of releases. RequireJS is the one i'm specifically looking at just now. Building the Javascript AMD support for RequireJS in DataTables is relatively simple, however, DataTables doesn't really make a lot of sense without some styling.
I publish a number of styling integrations (Bootstrap, Foundation, jQuery UI and DataTables own default with others planned) so I'd like to have something like require(['jquery', 'datatables.net-bs'], ... ); which will include DataTables and the Bootstrap styling for DataTables.
I could simply list a bunch of <link> tags for folks to include, but if I do that, I might as well just publish the <script> tags and forego RequireJS altogether.
I know that CSS is not supported by the RequireJS core, but I was hoping to use the require-css plug-in. That works well, but I can't find a way to have a module name include both the JS and CSS.
I found that the config.paths option for a module could specify multiple files in an array, so I tried:
'datatables.net-bs': [
'require-css!//nightly.datatables.net/css/dataTables.bootstrap.min',
'//nightly.datatables.net/js/dataTables.bootstrap.min',
]
But the plug-ins operate on the module name, not the path. I had a look at the plug-ins API but can't see an option to add a plug-in at that point (unless anyone knows better)?
If that isn't the best approach, can anyone suggest what is a better one?
This is what I have tried: http://jsfiddle.net/coaqsjkv/ - note that the CSS "plug-in" is not resolved at the path level giving a 404.
I could have the require list all the JS files and CSS files needed - but that seems very verbose (three files for DataTables with Bootstrap styling for example).
Any insights very welcome.

Related

How can I force old, compiled jquery plugins to use a specific version of jQuery in WordPress?

I have a client who had a very complex jQuery app custom built by a previous developer within his WordPress site. Its functionality is cleanly broken out into several scripts which get minified together with the libraries they depend on. The libraries rely on an old version of jQuery (3.3.1). The site is complex and we need to be able to use the current version of jQuery to allow other plugins we're using to continue to keep up with upgrades.
The libraries include c. 2018 versions of:
Select2
Isotope
SpriteSpin
EasyResponsiveTabs
ImagesUploaded
jQuery Viewport
Some of these are minified/uglified.
I've used best practices to load jQuery 3.3.1 into a variable jQuery3_3_1 with noconflict();
It's rather easy to change standard jQuery to use jQuery3_3_1. But I need a way to force the libraries to use jQuery3_3_1, otherwise they are not recognized by the scripts (and some of them will have issues using a different version of jQuery than they were built in). Most of these use requireJs(), and I've seen instructions for setting up requirejs.config() code in the footer that will define "jquery" to be a particular version. Doing this would be a great solution, but I have no idea how to get these uglified scripts to use it.
I've read through several similar inquiries, but none have addressed forcing a jQuery version on minified/uglified code. Others speak to a level of expertise in jQuery module development that I don't have and don't have time to scale into.
Is there a way to get all these modules that use require('jquery') to have that reference jQuery3_3_1? I'd love it if there were a way to say, "For all the files that live in this directory, jQuery/jquery (there are 2 ways it is called) means jQuery3_3_1/jquery3.3.1".
Or being that it's a Wordpress site, could this be defined in the wp_enqueue_script() call?
Many thanks for your help!

XPages Is it possible loading external javascript libraries via AMD loader?

In Domino 9 dojo comes with the AMD loader which seems to be interfering with loading of external javascript libraries eg Jquery Mobile, Fullcalendar.
The quick solution is to load these external libraries before the dojo libraries. But this requires the Xpage property: "Use runtime optimized Javascript and CSS resources" to be set.
The problem with this is that images referenced in compressed css files will break. Eg font-awesome, jqueryui.
This is a major flaw in the product that these references have to be recoded in the css files for it to work.
So the question is can eg fulcalendar and it's dependencies be loaded via AMD in Xpages so we don't have to recode all css files referencing images?
What exatly is your problem with loading jquery. I am loading jquery and other js libraries like select2, dgrowl, jgrid without any problems
When using the "Use runtime optimized Javascript and CSS resources" setting, there are some additional options you can set directly in xsp.properties to stop aggregation of CSS files like font-awesome. In this instance use 'xsp.resources.aggregate.css=false' and you will be good to go.
See http://lotusnotus.com/lotusnotus_en.nsf/dx/xpages-performance-dojo-widgets-and-resource-aggregation.htm for full details of all of the options.

Using Two Customized Versions of Zurb's Foundation Framework in one Web Project

My organization has created an ASP.NET Web Forms template with Foundation 4 baked directly into it. The problem is they didn't include all of the wonderful features available (i.e. the block grid). I'd really like to use the block grid, so what would be the best approach of downloading a customized version of Foundation and having it exist with another customized version in the same project?
I have a folder called App_Assets and this is where they demand we put any custom scripts.
I'm certain this is not the answer you're looking for, but the Zurb Foundation FAQ states:
6. How do I use multiple versions of Foundation?
You don't want to use multiple versions on a single project. If you
are using different versions for different projects, we've got you
covered. You can easily use a system like Bundler to define a version
(with the gem version). This lets you compile your CSS against
whatever version you'd like. If you're using vanilla CSS, you
shouldn't have a problem since you aren't compiling against a gem.
(emphasis mine)
So it doesn't look like there is a (supported) way to do this. Not to say that you won't be able to find a way to make it happen.
I think, there is only one safe way to include foundation 5 in your project.
- include foundation 5 files in your project and set variables $include-html-classes: false;
- use mixins to generate components that you need
for example:
#import "foundation/components/block-grid";
.name-o-your-block-grid{
#mixin block-grid();
}
information about all variables you can find in th source:
https://github.com/zurb/foundation/blob/master/scss/foundation/components/_block-grid.scss

using requirejs for collections of plugins

I am using requirejs so that I don't have every single script in the head tag for every page. The main motive behind switching to use requirejs is that we have plugins such as CodeMirror, with like 15 plugins to extend that too.
What I want to avoid is having for example:
require(["cm", "cmxml", "cmcss", "cmcodefold", "cmfoldgutter", "cmbracefold", "cmcommentfold" ....], fn);
I'd like to have this as just require(["cm"], fn); and automatically include all of the plugins with this. I'd also like to keep the plugins separate, so combining all the files into CodeMirror.js is not an option.
What I am wondering, before I go creating my own functions or modifying 3rd party code for this, is whether requirejs allows this kind of loading in any case? I have looked at the docs a lot and can't find anything, but that doesn't mean I haven't missed it or that it isn't documented. Thanks in advance.
Well I've managed to get this working using a shim for a script called cminit.js - the deps array simply lists all of the plugins for CodeMirror, which in turn have a dependency on CodeMirror which in turn has a dependency on jQuery. So one call to require for cminit.js automagically means that jQuery exists.
It works, but I'm not sure how much of this is best practice. Feel free to comment if you have a better way to do this.

Managing jQuery Plugins

Often, when working with jQuery, the need arises to include multiple plugins. This can quickly become messy work, especially when some plugins require additional components (images and CSS files).
What are some of the "recommended" ways to:
a. Manage the required files/components (.js, .css and images) in a way that is easy to maintain, and;
b. Keep these plugin packages updated to the latest versions
I'm not necessarily looking for a tool to do this (although one that could perform this management would be useful, I suppose), but more of a way of thinking.
Update: These days there is Bower, Component and Browserify which take care of all of the following for us automatically.
I'm surprised no one has covered what I do yet. So here's how I manage scripts and resources.
I have each project I work on setup with SVN. Nearly all of the scripts I include have a SVN mirror (github has svn these days) this means that I can then use SVN externals and fetch whatever branch or version or whatever I want of that project directly into the projects scripts folder. As we are using SVN, it is easy to track, manage and update these scripts.
If a project is not on SVN, then I just add it to a common SVN project I have made, so for instance Project A and Project B, both use jquery-project-not-in-svn, so we stick jquery-project-not-in-svn into our common project's SVN repository, and then use SVN externals on Projects A and B to reference it - as explained before.
Now that covers managing, fetching and updating.
Here is how I cover script inclusions and requests.
As each project now has it's own scripts directory that contains all the scripts it needs (which is managed by SVN externals), we now have to worry about minifying them to reduce load on our server. Each project has a Makefile in it's root, which contains the command update. This command will perform the following:
Perform a SVN update (this will update all SVN externals appropriately)
Once that is done, it will pack and minify all the js files into scripts/all.js and scripts/all.min.js
I can't share the exact Makefile but I can share one which is public that handles packing/merging and minification of CSS and Javascript. Here is the link:
http://github.com/balupton/jquery-sparkle/blob/9921fcbf1cbeab7a4f2f875a91cb8548f3f65721/Makefile
By doing these things, we have achieved:
Management of external script resources over multiple projects
Updating of appropriate script resources automatically
Packing all used script resources of the project into one file
Minifying that file, such that only one JS request and one CSS request are performed.
So good luckmate, feel free to post a comment if you would like to learn more.
I would recommend not updating them unless you are experiencing a problem with the version you have or you would like to use a new feature available in the updated plugin. As the saying goes, if it ain't broke, don't fix it.
My own personal "recommended" way is to keep all my JavaScript files in one include folder, all CSS files in another, and all images in a third directory. I write shortcut functions for my projects that I can then use like <?php scriptlink( 'jquery.tooltip' ); ?> or <?php stylelink( 'jquery.thickbox' ); ?>. Each shortcut function takes a filename (only) as an argument and outputs the full HTML tag for that resource type, i.e. (in order) <script type="text/javascript" src="/includes/js/jquery.tooltip.js"></script> or <link rel="stylesheet" href="/includes/css/jquery.thickbox.css" />
Most jQuery plugins I've run across that require images allow either specifying a configuration variable in the script itself or in the code used to invoke the plugin. Stylesheets are quite easily included without mucking about with the script.
So far this method has kept me pretty sane, so I think it works rather well. I don't tear my hair out over where I stuck a particular plugin; I just include it with a function. (The system also supports subdirectories of the include directory, so e.g. <?php scriptlink( 'ui/accordion' ); ?> equals <script type="text/javascript" src="/includes/js/ui/accordion.js"></script>.)
YMMV of course, but the only issue I've had at all is with upgrades when plugin authors start distributing a jquery.plugin.pack.js version instead of jquery.plugin.min.js or vice versa, because I actually have to remember to change the filenames I look for.
(Since I've omitted the implementation of those simple functions, perhaps your version will check for different variants of the file name given. If the argument to scriptlink() is jquery.plugin, the function might check the file system to see if jquery.plugin.pack.js exists, and if not look for jquery.plugin.min.js, and if not look for jquery.plugin.js, etc.)
CDNs are great but not for debugging. Sometimes debugging really requires local access
to the scripts and CDNs are useless until in production mode. For this reason I still like
to keep both debug and minified versions around then compare results and benchmark response time until we shift to production.
All of my jQuery plugins are organised into subfolders which include the version number e.g.
/assets/js/plugin.1.4.1/plugin.1.4.1.min.js
/assets/js/plugin.1.4.1/images/image.gif
If I need to update to 1.4.2 I can drop it in a new folder without too many problem, I can even use a specific version of the plugin in different parts of the site if needed. When I site is large and your using a few different plugins it's helpful to quickly see version numbers without digging around source comments in a plugin.js file.
If a plugin requires CSS I will take the base styles out of the plugin CSS and bundle these in with my main stylesheet, requesting additional CSS files is expensive and 9 times out of 10 it will be customised anyway. Likewise with images, if I'm doing any image customisation I will bundle these into my main image sprite, otherwise I'll just link to the images into that plugin.1.4.1 directory.
Yes, you end up with a few more files in your repo but it means:
you can easily upgrade plugins just by updating your paths
you can debug plugin issues easier because you can see how out of date you are
you can roll back to an earlier version if everything breaks
You could utilize the Google CDN (Content Delivery Network) for more popular plug-ins. Google keeps it up-to-date, you can quickly choose/switch between versions, and you also get the benefits of caching from other websites that use CDN.
Example for jQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
And, if you want to use a higher version automatically, change the version to 1.4 (automatic 1.4.x updates) or even 1 (automatic 1.x.x updates). Unfortunately not all plug-ins are available, but many of the major ones are.

Categories

Resources