This issue might seem minor but I always forget the names (exact naming) or number of script files I need to get some features working in MVC or Webforms. In addition, in my applications that require a specific client side feature, I might need a series of dependent scripts to make it work. Failing to include all of them often gives ambiguous errors or the functionality or feature just doesn't work.
To that end, I have created a ScriptHelper to allow me to express those dependencies as a singular name and have all the script dependencies (or CSS) emitted for me.
The library is currently hosted on bitbucket here http://bitbucket.org/glav/mvc-script-dependency-extension
The ScriptHelper I have written is a little raw, but you can define an XML file that expresses script names and its dependencies. The script helper then allows you to provide that single name and all dependent scripts are emitted in the page.
For example, in the page you can do:
<%= ScriptHelper.RequiresScript(ScriptName.jqueryValidateUnobtrusive) %>
<%= ScriptHelper.RequiresScript(“jQuery-validate-unobtrusive”) %>
And you would get
Additionally, you could do:
<%= ScriptHelper.RequiresScript("All") %>
And you would get the following emitted into your page:
The dependency file looks something like:
<?xml version="1.0" encoding="utf-8" ?> <Dependencies ReleaseSuffix="min" DebugSuffix="debug"> <Dependency Name="jQuery-validate-unobtrusive" Type="js"> <ScriptFile>~/Scripts/jquery.validate.unobtrusive.js</ScriptFile> <RequiredDependencies> <Name>jquery</Name> <Name>jQuery-validate</Name> </RequiredDependencies> </Dependency> <Dependency Name="jQuery-validate" Type="js"> <ScriptFile>~/Scripts/jquery.validate.js</ScriptFile> <RequiredDependencies> <Name>jquery</Name> </RequiredDependencies> </Dependency> <Dependency Name="jQuery" Type="js"> <ScriptFile>~/Scripts/jquery-1.4.1.js</ScriptFile> </Dependency> <!— rest of dependencies …. -->
The ReleaseSuffix and DebugSuffix also act to rename a dependency file that is output to the page. These are not mandatory but it is not uncommon to host debug versions of your scripts when doing development and release/minified versions of your scripts in production. So for example, if we have a script file dependency defined as Something.js, then it will be renamed to Something.min.js in release mode and Something.debug.js in debug mode when output to the page. If not specified, the emitted dependency is left as is.
Finally, you can also specify multiple dependencies on the same line like so:
<%= ScriptHelper.RequiresScript("Microsoft-Mvc-Validation", "jQuery") %>
And all dependent scripts will be included for you without duplicating anything. Obviously the script names must be the same as what is defined in the script dependency file. I have used a static class to hold these constants and you could easily substitute your own as its just strings.
It also supports expressing CSS dependencies. For example, with the following dependency definitions:
<Dependency Name="SiteWideStyle" Type="css"> <ScriptFile>~/Content/Site.css</ScriptFile> </Dependency> <Dependency Name="HomeStyle" Type="css"> <ScriptFile>~/Content/Home.css</ScriptFile> <RequiredDependencies> <Name>SiteWideStyle</Name> </RequiredDependencies> </Dependency>
You can then include the following in your <head> section of your pages
<%= ScriptHelper.RequiresScript("HomeStyle") %>
And you would get
<link href='/Content/Site.css' rel='stylesheet' type='text/css' /> <link href='/Content/Home.css' rel='stylesheet' type='text/css' />
Currently, the ScriptHelper I have written supports resolving the dependency file in a few local locations, but I plan on extending it support remote locations via HTTP.
This type of thing could reduce multiple script include to a single line in a web page or view. In addition, you could have dependency files centrally located on a remote server either in the cloud or internal to your organisation, so that dependencies are always resolved via this file which can be maintained and updated as new dependencies and/or later versions of the scripts are available or required.
There is also nothing stopping you from naming your dependencies more component oriented in nature. For example you might name a dependency “AjaxGrid”, and that may load in jQuery core script, jQuery UI custom scripts, as well as some of your own custom scripts required to get this component working.
I have been using this library primarily with ASP.NET MVC projects, but it is just a set of static methods that could also be used within an ASP.NET Webforms application as well.
Feel free to leave comments/issues on the hosting site here http://bitbucket.org/glav/mvc-script-dependency-extension