I have followed this question to get started using RequireJS as well as the RequireJS jQuery Docs. I have not been able to find how to reuse packages in a single file or how to structure the file itself. The following code works as expected and displays the text on the page. The first part of the javascript is automatically created see this question for more details.
The part that I am concerned with is the AMDSpecs.js init method. This seems counterproductive to the AMD specs. If this is the case, do I need to call a require each time I need jQuery? I hope I am explaining what I mean, please ask if you need more information.
HTML
<div id="output"></div>
Javascript
<script src="/MVCTesting/Scripts/ThirdParty/RequireJS/require.js"></script>
<script type="text/javascript">
require( [ "/MVCTesting/Scripts/AMD/core.js" ], function() {
require( ["jquery", "/MVCTesting/Scripts/AMD/views/jquery/AMDSpecs.js"],
function($, pm) {
if (pm != undefined && pm.init) {
pm.init($);
}
});
});
</script>
/*AMDSpecs.js*/
define(function () {
//Do setup work here
return {
$: undefined,
setupEvents: function () {
$("#output").text("jQuery is working!");
},
init: function ($) {
this.$ = $;
require(["Views/JQuery/AMDSpecs"], function (specs) {
specs.setupEvents();
});
}
};
});
UPDATE
Here is my working solution after Donald's answer with all code. Note, I still need to include the .js in the module name, but this simplifies the process a lot.
HtmlExtension.cs
/// <summary>
/// An Html helper for Require.js
/// </summary>
/// <param name="helper"></param>
/// <param name="module">Location of the main.js file.</param>
/// <returns></returns>
public static MvcHtmlString RequireJS(this HtmlHelper helper, string module)
{
const string jsLocation = "Scripts/AMD/";
//Don't build require string if there is not an amd script
if (!File.Exists(helper.ViewContext.HttpContext.Server.MapPath(
GetAbsolutePath(Path.Combine(jsLocation, module + ".js")))))
{
return null;
}
var require = new StringBuilder();
require.AppendLine(" require( [\"" + GetAbsolutePath(jsLocation + module + ".js") + "\"], function(pm) {");
require.AppendLine(" if (pm != undefined && pm.init) {");
require.AppendLine(" pm.init();");
require.AppendLine(" }");
require.AppendLine(" });");
return new MvcHtmlString(require.ToString());
}
/// <summary>
/// Convert the path to work in IIS for MVC
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static string GetAbsolutePath(string path)
{
return VirtualPathUtility.ToAbsolute("~/" + path);
}
/// <summary>
/// Create the include for RequireJS based on the current page
/// </summary>
/// <param name="helper"></param>
/// <returns></returns>
public static MvcHtmlString ViewSpecificRequireJS(this HtmlHelper helper)
{
var action = helper.ViewContext.RouteData.Values["action"];
var controller = helper.ViewContext.RouteData.Values["controller"];
return helper.RequireJS(string.Format("views/{0}/{1}", controller, action));
}
_Layout.cshtml (MVCTesting is my project name)
<script data-main="/MVCTesting/Scripts/AMD/core.js" src="~/Scripts/ThirdParty/RequireJS/require.js"></script>
AMDSpecs.js
define(["jquery"], function ($) {
//Do setup work here
return {
setupEvents: function () {
$("#output").text("jQuery is working!");
},
init: function () {
this.setupEvents();
}
};
});