diff --git a/RequireJsNet.Examples/RequireJS.complex.json b/RequireJsNet.Examples/RequireJS.complex.json
index 001cfe7..f2e8b5a 100644
--- a/RequireJsNet.Examples/RequireJS.complex.json
+++ b/RequireJsNet.Examples/RequireJS.complex.json
@@ -1,15 +1,19 @@
{
- "paths": {
- "jquery": [ "http://no-domain.unknown/jquery-2.1.3", "jquery-2.1.3" ],
- "jqMin": "jquery-2.1.3.min",
- "req1": "req1",
- "req2": "req2",
- "jquery-validate": {
- "path": "jquery.validate",
- "defaultBundle": "jqValidate"
- },
- "jquery-validate-unobtrusive": "jquery.validate.unobtrusive"
+ "paths": {
+ "jquery": [ "http://no-domain.unknown/jquery-2.1.3", "jquery-2.1.3" ],
+ "jqMin": "jquery-2.1.3.min",
+ "req1": "req1",
+ "req2": "req2",
+ "jquery-validate": {
+ "path": "jquery.validate",
+ "defaultBundle": "jqValidate"
},
+ "jquery-validate-unobtrusive": "jquery.validate.unobtrusive"
+ },
+ "packages": [
+ "cart",
+ { "name": "store", "main": "store", "location": "/Scripts/CommonJS/store" }
+ ],
"shim": {
"jquery-validate": {
"deps": [ "jquery" ],
diff --git a/RequireJsNet.Examples/RequireJsNet.Examples.csproj b/RequireJsNet.Examples/RequireJsNet.Examples.csproj
index 81f4d34..4a18b46 100644
--- a/RequireJsNet.Examples/RequireJsNet.Examples.csproj
+++ b/RequireJsNet.Examples/RequireJsNet.Examples.csproj
@@ -157,6 +157,7 @@
+
@@ -187,6 +188,8 @@
+
+
diff --git a/RequireJsNet.Examples/Scripts/CommonJS/store/store.js b/RequireJsNet.Examples/Scripts/CommonJS/store/store.js
new file mode 100644
index 0000000..0475710
--- /dev/null
+++ b/RequireJsNet.Examples/Scripts/CommonJS/store/store.js
@@ -0,0 +1,2 @@
+//CommonJS package format
+alert('store/store.js loaded');
diff --git a/RequireJsNet.Examples/Scripts/CommonJS/store/util.js b/RequireJsNet.Examples/Scripts/CommonJS/store/util.js
new file mode 100644
index 0000000..e75179b
--- /dev/null
+++ b/RequireJsNet.Examples/Scripts/CommonJS/store/util.js
@@ -0,0 +1,2 @@
+//CommonJS package format
+alert('store/util.js loaded');
diff --git a/RequireJsNet.Examples/Scripts/Controllers/Root/Home/complexLoad.js b/RequireJsNet.Examples/Scripts/Controllers/Root/Home/complexLoad.js
index 7480d0a..9e1d638 100644
--- a/RequireJsNet.Examples/Scripts/Controllers/Root/Home/complexLoad.js
+++ b/RequireJsNet.Examples/Scripts/Controllers/Root/Home/complexLoad.js
@@ -1,5 +1,12 @@
define(['req1', "jquery"], function(req1, $) {
$(function () {
alert('jquery loaded');
+
+ require(["cart", "store", "store/util"], function (cart, store, util) {
+
+ alert('commonJS packages cart, store and util has been loaded');
+
+ });
+
});
});
\ No newline at end of file
diff --git a/RequireJsNet.Examples/Scripts/cart/main.js b/RequireJsNet.Examples/Scripts/cart/main.js
new file mode 100644
index 0000000..50b46ab
--- /dev/null
+++ b/RequireJsNet.Examples/Scripts/cart/main.js
@@ -0,0 +1,2 @@
+//CommonJS package format
+alert('cart/main.js loaded');
diff --git a/RequireJsNet.Tests/ConfigMergerShould.cs b/RequireJsNet.Tests/ConfigMergerShould.cs
index dbe0b34..c625c33 100644
--- a/RequireJsNet.Tests/ConfigMergerShould.cs
+++ b/RequireJsNet.Tests/ConfigMergerShould.cs
@@ -553,5 +553,48 @@ public void UnifyBundleItemsForSameId()
CustomAssert.JsonEquals(expected, merged);
}
+
+ [Fact]
+ public void ReplacePackagesWithSameName()
+ {
+ var packageA1 = new RequirePackage("a", "main");
+ var packageA2 = new RequirePackage("a", "start", "/somewhere");
+
+ var firstConfig = ConfigurationCreators.CreateCollectionWithPackages(packageA1);
+ var secondConfig = ConfigurationCreators.CreateCollectionWithPackages(packageA2);
+
+ var merger = ConfigurationCreators.CreateBundleProcessingConfigMerger(firstConfig, secondConfig);
+ var merged = merger.GetMerged();
+
+ var expected = ConfigurationCreators.CreateEmptyCollection();
+ expected.Packages.PackageList = new List
+ {
+ new RequirePackage("a", "start", "/somewhere")
+ };
+
+ CustomAssert.JsonEquals(expected, merged);
+ }
+
+ [Fact]
+ public void AppendPackagesWithDifferentName()
+ {
+ var packageA1 = new RequirePackage("a", "main");
+ var packageA2 = new RequirePackage("b", "start", "/somewhere");
+
+ var firstConfig = ConfigurationCreators.CreateCollectionWithPackages(packageA1);
+ var secondConfig = ConfigurationCreators.CreateCollectionWithPackages(packageA2);
+
+ var merger = ConfigurationCreators.CreateBundleProcessingConfigMerger(firstConfig, secondConfig);
+ var merged = merger.GetMerged();
+
+ var expected = ConfigurationCreators.CreateEmptyCollection();
+ expected.Packages.PackageList = new List
+ {
+ new RequirePackage("a", "main"),
+ new RequirePackage("b", "start", "/somewhere")
+ };
+
+ CustomAssert.JsonEquals(expected, merged);
+ }
}
}
diff --git a/RequireJsNet.Tests/DataCreation/ConfigurationCreators.cs b/RequireJsNet.Tests/DataCreation/ConfigurationCreators.cs
index b513dab..685fadb 100644
--- a/RequireJsNet.Tests/DataCreation/ConfigurationCreators.cs
+++ b/RequireJsNet.Tests/DataCreation/ConfigurationCreators.cs
@@ -17,6 +17,9 @@ public static ConfigurationCollection CreateEmptyCollection()
collection.Paths = new RequirePaths();
collection.Paths.PathList = new List();
+ collection.Packages = new RequirePackages();
+ collection.Packages.PackageList = new List();
+
collection.AutoBundles = new AutoBundles();
collection.AutoBundles.Bundles = new List();
@@ -41,6 +44,14 @@ public static ConfigurationCollection CreateCollectionWithPaths(params RequirePa
return collection;
}
+ public static ConfigurationCollection CreateCollectionWithPackages(params RequirePackage[] packages)
+ {
+ var collection = CreateEmptyCollection();
+ collection.Packages = new RequirePackages();
+ collection.Packages.PackageList = packages.ToList();
+ return collection;
+ }
+
public static ConfigurationCollection CreateCollectionWithShims(params ShimEntry[] shim)
{
var collection = CreateEmptyCollection();
diff --git a/RequireJsNet.Tests/JsonReaderShould.cs b/RequireJsNet.Tests/JsonReaderShould.cs
index e0a1b88..5002c60 100644
--- a/RequireJsNet.Tests/JsonReaderShould.cs
+++ b/RequireJsNet.Tests/JsonReaderShould.cs
@@ -61,6 +61,38 @@ public void ReadPathArray()
CustomAssert.JsonEquals(expected, config);
}
+ [Fact]
+ public void ReadPackagesArray()
+ {
+ var expectedPackages = new[]
+ {
+ new RequirePackage("cart", "main"),
+ new RequirePackage("store", "store")
+ };
+ var expectedCollection = ConfigurationCreators.CreateCollectionWithPackages(expectedPackages);
+
+ var config = ReadJson(new TestFileReader());
+
+ Assert.Equal(2, config.Packages.PackageList.Count);
+ CustomAssert.JsonEquals(expectedCollection, config);
+ }
+
+ [Fact]
+ public void SerializesPackagesInRequireJSFormat()
+ {
+ var expected = "var require = {\"baseUrl\":\"\",\"locale\":\"en\",\"urlArgs\":null,\"waitSeconds\":7,\"paths\":{},\"packages\":[{\"name\":\"cart\",\"main\":\"main\"},{\"name\":\"store\",\"main\":\"store\"}],\"shim\":{},\"map\":{}};";
+
+ var config = new RequireRendererConfiguration();
+ var collection = ConfigurationCreators.CreateCollectionWithPackages(
+ new RequirePackage("cart", "main"),
+ new RequirePackage("store", "store")
+ );
+ var outputConfig = RequireJsHtmlHelpers.createOutputConfigFrom(collection, config, "en");
+ var actual = Helpers.JavaScriptHelpers.SerializeAsVariable(outputConfig, "require");
+
+ Assert.Equal(expected, actual);
+ }
+
[Fact]
public void ReadShimWithExports()
{
diff --git a/RequireJsNet.Tests/RequireJsNet.Tests.csproj b/RequireJsNet.Tests/RequireJsNet.Tests.csproj
index 6696670..1e09dcd 100644
--- a/RequireJsNet.Tests/RequireJsNet.Tests.csproj
+++ b/RequireJsNet.Tests/RequireJsNet.Tests.csproj
@@ -68,6 +68,7 @@
+
@@ -93,6 +94,7 @@
+
diff --git a/RequireJsNet.Tests/RequirePackageShould.cs b/RequireJsNet.Tests/RequirePackageShould.cs
new file mode 100644
index 0000000..1e72212
--- /dev/null
+++ b/RequireJsNet.Tests/RequirePackageShould.cs
@@ -0,0 +1,39 @@
+using RequireJsNet.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace RequireJsNet.Tests
+{
+ public class RequirePackageShould
+ {
+ [Fact]
+ public void InitializeWithOnlyName()
+ {
+ var name = "package1";
+
+ var actual = new RequirePackage(name);
+
+ Assert.Equal(name, actual.Name);
+ Assert.Equal("main", actual.Main);
+ Assert.Equal(null, actual.Location);
+ }
+
+ [Fact]
+ public void InitializeWithAllProperties()
+ {
+ var name = "package2";
+ var main = "start";
+ var location = "/Scripts/CommonJS/package2";
+
+ var actual = new RequirePackage(name, main, location);
+
+ Assert.Equal(name, actual.Name);
+ Assert.Equal(main, actual.Main);
+ Assert.Equal(location, actual.Location);
+ }
+ }
+}
diff --git a/RequireJsNet.Tests/TestData/JsonReaderShould/ReadPackagesArray.json b/RequireJsNet.Tests/TestData/JsonReaderShould/ReadPackagesArray.json
new file mode 100644
index 0000000..8e4ce60
--- /dev/null
+++ b/RequireJsNet.Tests/TestData/JsonReaderShould/ReadPackagesArray.json
@@ -0,0 +1,6 @@
+{
+ "packages": [
+ "cart",
+ { "name": "store", "main": "store" }
+ ]
+}
diff --git a/RequireJsNet/Configuration/ConfigMerger.cs b/RequireJsNet/Configuration/ConfigMerger.cs
index 1c453cc..d7487d7 100644
--- a/RequireJsNet/Configuration/ConfigMerger.cs
+++ b/RequireJsNet/Configuration/ConfigMerger.cs
@@ -26,6 +26,8 @@ public ConfigMerger(List collections, ConfigLoaderOptio
this.collections = collections;
finalCollection.Paths = new RequirePaths();
finalCollection.Paths.PathList = new List();
+ finalCollection.Packages = new RequirePackages();
+ finalCollection.Packages.PackageList = new List();
finalCollection.Shim = new RequireShim();
finalCollection.Shim.ShimEntries = new List();
finalCollection.Map = new RequireMap();
@@ -46,6 +48,11 @@ public ConfigurationCollection GetMerged()
MergePaths(coll);
}
+ if (coll.Packages != null && coll.Packages.PackageList != null)
+ {
+ MergePackages(coll);
+ }
+
if (coll.Shim != null && coll.Shim.ShimEntries != null)
{
MergeShims(coll);
@@ -99,6 +106,24 @@ private void MergePaths(ConfigurationCollection collection)
}
}
+ private void MergePackages(ConfigurationCollection collection)
+ {
+ var finalPackages = finalCollection.Packages.PackageList;
+ foreach (var package in collection.Packages.PackageList)
+ {
+ var existing = finalPackages.Where(r => r.Name == package.Name).FirstOrDefault();
+ if (existing != null)
+ {
+ existing.Main = package.Main;
+ existing.Location = package.Location;
+ }
+ else
+ {
+ finalPackages.Add(package);
+ }
+ }
+ }
+
private void MergeShims(ConfigurationCollection collection)
{
var finalShims = finalCollection.Shim.ShimEntries;
diff --git a/RequireJsNet/Configuration/JsonReader.cs b/RequireJsNet/Configuration/JsonReader.cs
index bb6d04c..29ecfcf 100644
--- a/RequireJsNet/Configuration/JsonReader.cs
+++ b/RequireJsNet/Configuration/JsonReader.cs
@@ -70,6 +70,7 @@ private ConfigurationCollection ProcessConfig()
var deserialized = (JObject)JsonConvert.DeserializeObject(text);
collection.FilePath = Path;
collection.Paths = GetPaths(deserialized);
+ collection.Packages = GetPackages(deserialized);
collection.Shim = GetShim(deserialized);
collection.Map = GetMap(deserialized);
@@ -133,6 +134,38 @@ private static RequirePath requirePathFrom(JProperty prop)
return result;
}
+ private RequirePackages GetPackages(JObject document)
+ {
+ var packages = new RequirePackages();
+ packages.PackageList = new List();
+
+ if (document != null && document["packages"] != null)
+ {
+ packages.PackageList = document["packages"]
+ .Select(r => requirePackageFrom(r))
+ .ToList();
+ }
+
+ return packages;
+ }
+
+ private static RequirePackage requirePackageFrom(JToken token)
+ {
+ if (token is JValue)
+ {
+ var name = ((JValue)token).Value();
+ return new RequirePackage(name);
+ }
+ else
+ {
+ var packageObj = (JObject)token;
+ var name = (string)packageObj["name"];
+ var main = (string)packageObj["main"];
+ var location = (string)packageObj["location"];
+ return new RequirePackage(name, main, location);
+ }
+ }
+
private RequireShim GetShim(JObject document)
{
var shim = new RequireShim();
diff --git a/RequireJsNet/Models/ConfigurationCollection.cs b/RequireJsNet/Models/ConfigurationCollection.cs
index b651519..7335849 100644
--- a/RequireJsNet/Models/ConfigurationCollection.cs
+++ b/RequireJsNet/Models/ConfigurationCollection.cs
@@ -18,6 +18,9 @@ internal class ConfigurationCollection
[JsonProperty(PropertyName = "paths")]
public RequirePaths Paths { get; set; }
+ [JsonProperty(PropertyName = "packages")]
+ public RequirePackages Packages { get; set; }
+
[JsonProperty(PropertyName = "shim")]
public RequireShim Shim { get; set; }
diff --git a/RequireJsNet/Models/JsonRequireOutput.cs b/RequireJsNet/Models/JsonRequireOutput.cs
index f25793d..fae6a19 100644
--- a/RequireJsNet/Models/JsonRequireOutput.cs
+++ b/RequireJsNet/Models/JsonRequireOutput.cs
@@ -28,6 +28,9 @@ public class JsonRequireOutput
[JsonProperty(PropertyName = "paths")]
public Dictionary> Paths { get; set; }
+ [JsonProperty(PropertyName = "packages")]
+ public List Packages { get; set; }
+
[JsonProperty(PropertyName = "shim")]
public Dictionary Shim { get; set; }
diff --git a/RequireJsNet/Models/RequirePackage.cs b/RequireJsNet/Models/RequirePackage.cs
new file mode 100644
index 0000000..c0ce83d
--- /dev/null
+++ b/RequireJsNet/Models/RequirePackage.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RequireJsNet.Models
+{
+ public class RequirePackage
+ {
+ [JsonProperty(PropertyName = "name")]
+ public string Name { get; set; }
+
+ [JsonProperty(PropertyName = "main")]
+ public string Main { get; set; }
+
+ [JsonProperty(PropertyName = "location", NullValueHandling = NullValueHandling.Ignore)]
+ public string Location { get; set; }
+
+ public RequirePackage(string name, string main = "main", string location = null)
+ {
+ this.Name = name;
+ this.Main = main ?? "main";
+ this.Location = location;
+ }
+ }
+}
diff --git a/RequireJsNet/Models/RequirePackages.cs b/RequireJsNet/Models/RequirePackages.cs
new file mode 100644
index 0000000..2f5db5d
--- /dev/null
+++ b/RequireJsNet/Models/RequirePackages.cs
@@ -0,0 +1,16 @@
+// RequireJS.NET
+// Copyright VeriTech.io
+// http://veritech.io
+// Dual licensed under the MIT and GPL licenses:
+// http://www.opensource.org/licenses/mit-license.php
+// http://www.gnu.org/licenses/gpl.html
+
+using System.Collections.Generic;
+
+namespace RequireJsNet.Models
+{
+ public class RequirePackages
+ {
+ public List PackageList { get; set; }
+ }
+}
diff --git a/RequireJsNet/RequireJsHtmlHelpers.cs b/RequireJsNet/RequireJsHtmlHelpers.cs
index dbfb588..d9aa210 100644
--- a/RequireJsNet/RequireJsHtmlHelpers.cs
+++ b/RequireJsNet/RequireJsHtmlHelpers.cs
@@ -62,35 +62,9 @@ public static MvcHtmlString RenderRequireJsSetup(
var locale = config.LocaleSelector(html);
- var outputConfig = new JsonRequireOutput
- {
- BaseUrl = config.BaseUrl,
- Locale = locale,
- UrlArgs = config.UrlArgs,
- WaitSeconds = config.WaitSeconds,
- Paths = resultingConfig.Paths.PathList.ToDictionary(r => r.Key, r => r.Value),
- Shim = resultingConfig.Shim.ShimEntries.ToDictionary(
- r => r.For,
- r => new JsonRequireDeps
- {
- Dependencies = r.Dependencies.Select(x => x.Dependency).ToList(),
- Exports = r.Exports
- }),
- Map = resultingConfig.Map.MapElements.ToDictionary(
- r => r.For,
- r => r.Replacements.ToDictionary(x => x.OldKey, x => x.NewKey))
- };
-
- config.ProcessConfig(outputConfig);
+ var outputConfig = createOutputConfigFrom(resultingConfig, config, locale);
- var options = new JsonRequireOptions
- {
- Locale = locale,
- PageOptions = RequireJsOptions.GetPageOptions(html.ViewContext.HttpContext),
- WebsiteOptions = RequireJsOptions.GetGlobalOptions(html.ViewContext.HttpContext)
- };
-
- config.ProcessOptions(options);
+ var options = createOptionsFrom(html.ViewContext.HttpContext, config, locale);
var configBuilder = new JavaScriptBuilder();
configBuilder.AddStatement(JavaScriptHelpers.SerializeAsVariable(options, "requireConfig"));
@@ -102,17 +76,57 @@ public static MvcHtmlString RenderRequireJsSetup(
var requireEntryPointBuilder = new JavaScriptBuilder();
requireEntryPointBuilder.AddStatement(
JavaScriptHelpers.MethodCall(
- "require",
+ "require",
(object)new[] { entryPointPath.ToString() }));
return new MvcHtmlString(
- configBuilder.Render()
+ configBuilder.Render()
+ Environment.NewLine
- + requireRootBuilder.Render()
+ + requireRootBuilder.Render()
+ Environment.NewLine
+ requireEntryPointBuilder.Render());
}
+ internal static JsonRequireOptions createOptionsFrom(System.Web.HttpContextBase httpContext, RequireRendererConfiguration config, string locale)
+ {
+ var options = new JsonRequireOptions
+ {
+ Locale = locale,
+ PageOptions = RequireJsOptions.GetPageOptions(httpContext),
+ WebsiteOptions = RequireJsOptions.GetGlobalOptions(httpContext)
+ };
+
+ config.ProcessOptions(options);
+ return options;
+ }
+
+ internal static JsonRequireOutput createOutputConfigFrom(ConfigurationCollection resultingConfig, RequireRendererConfiguration config, string locale)
+ {
+ var outputConfig = new JsonRequireOutput
+ {
+ BaseUrl = config.BaseUrl,
+ Locale = locale,
+ UrlArgs = config.UrlArgs,
+ WaitSeconds = config.WaitSeconds,
+ Paths = resultingConfig.Paths.PathList.ToDictionary(r => r.Key, r => r.Value),
+ Packages = resultingConfig.Packages.PackageList,
+ Shim = resultingConfig.Shim.ShimEntries.ToDictionary(
+ r => r.For,
+ r => new JsonRequireDeps
+ {
+ Dependencies = r.Dependencies.Select(x => x.Dependency).ToList(),
+ Exports = r.Exports
+ }),
+ Map = resultingConfig.Map.MapElements.ToDictionary(
+ r => r.For,
+ r => r.Replacements.ToDictionary(x => x.OldKey, x => x.NewKey))
+ };
+
+ config.ProcessConfig(outputConfig);
+
+ return outputConfig;
+ }
+
private static HashStore configObjectHash = new HashStore();
private static ConfigurationCollection GetCachedOverridenConfig(
diff --git a/RequireJsNet/RequireJsNet.csproj b/RequireJsNet/RequireJsNet.csproj
index 6e36186..cd82633 100644
--- a/RequireJsNet/RequireJsNet.csproj
+++ b/RequireJsNet/RequireJsNet.csproj
@@ -111,6 +111,8 @@
+
+