cujojs / curl

curl.js is small, fast, extensible module loader that handles AMD, CommonJS Modules/1.1, CSS, HTML/text, and legacy scripts.
https://github.com/cujojs/curl/wiki
Other
1.89k stars 216 forks source link

Hierarchical module loading #245

Open jbadeau opened 10 years ago

jbadeau commented 10 years ago

Hi,

I am working on an osgi like module system for javascript and I am looking into the concept of a parent-child (hierarchical) module loader. Basically like:

moduleC depends on moduleA if the loader for moduleC does not find moduleA then it looks for it in its parent loader and if it is still not found then it is loaded via http

Something similar to the java classloader.

Before i start looking at module loader code I was wondering if you ever saw a need for this and what you think would be the effort (crude estimate) to add it to curl?

unscriptable commented 10 years ago

Hey @jbadeau!

Currently, curl.js has hierarchical configuration of packages. If the loader for packageC (which contains your moduleC) is not configured for packageA (which contains your moduleA), then it looks in the a previous configuration snapshot for it. Every time you call curl.config(), another snapshot is created. The cache, however, is shared amongst all snapshots. I'm guessing this is not sufficient for your needs?

I think it would be possible, but probably a bit clunky to do what you're suggesting in curl.js. The problem is the single, global define(). Somehow, we'd have to ensure that each module registered itself into the correct loader.

Any ideas on this?

-- John

jbadeau commented 10 years ago

The hierarchy would look something like this:

OsgiFramework (root module loader) |- es4/5/6 |- when-2.7.1 |- poly-0.5.2 |- msgs-0.3.3 |- meld-1.3.0 |---- OsgiBundle1 (osgi bundle loader) |-------- jquery-1.9 |-------- knockout-2.3.0 |---- OsgiBundle2 (osgi bundle loader) |-------- jquery-2.0 |-------- knockout-3.0.0

each bundle gets its own loader and should not use any cache except perhaps for libs defined in the root loader.

unscriptable commented 10 years ago

Hey @jbadeau,

If the point is to only allow knockout 2.3 to see jquery 1.9 (and knockout 3.0 to see jquery 2.0), then this is already possible via embedded configs.

var config1 = {
    paths: {
        jquery: "//cdn.jquery.com/jquery1.9.1.min.js",
        knockout: "vendro/knockout-2.3.0/knockout"
    }
};

var config2 = {
    paths: {
        jquery: "//cdn.jquery.com/jquery2.0.1.min.js",
        knockout: "vendro/knockout-3.0.0/knockout"
    }
};

curl.config({
    packages: {
        package1: { location: 'app/package1', main: 'foo', config: config1 },
        package2: { location: 'app/package1', main: 'foo', config: config2 }
    }
});

Modules in package1 will see jquery 1.9.1 and knockout 2.3.0. Modules in package2 will see jquery 2.0.1 and knockout 3.0.0.

Is this what you need?

-- John

jbadeau commented 10 years ago

The com.cujojs.wire bundle manifest

{ "Manifest-Version":"1.0",

"Bundle-ManifestVersion":"2",

"Bundle-Localization":"nls/messages",

"Bundle-SymbolicName":"com.cujojs.wire;singleton:=true",

"Bundle-Version":"0.10.2",

"Bundle-Vendor":"%providerName",

"Bundle-Name":"%bundleName",

"Bundle-Description":"%bundleDescription",

"Bundle-ActivationPolicy":"lazy",

"Require-Bundle":{ "com.cujojs.meld":{"bundle-version":"[1,2)"}, "com.cujojs.when":{"bundle-version":"[1.5.0,2]"} },

"Export-Package":{ "when":{"version":"0.10.2"}, "when/builder":{"version":"0.10.2"}, "when/dojo":{"version":"0.10.2"}, "when/dom":{"version":"0.10.2"}, "when/dom/transform":{"version":"0.10.2"}, "when/lib":{"version":"0.10.2"}, "when/lib/dom":{"version":"0.10.2"}, "when/lib/graph":{"version":"0.10.2"}, "when/lib/loader":{"version":"0.10.2"}, "when/lib/plugin":{"version":"0.10.2"}, "when/lib/plugin-base":{"version":"0.10.2"} } }

Each bundle must

When the com.cujojs.wire bundle requires the when.js module the loader must:

I realize this is not how curl works. I'm just trying to think of how I could use curl instead of YET ANOTHER LOADER

currently when osgi starts up all bundle manifests are registered (not loaded). I could possibly generate the configs based on the dependency graphs

jbadeau commented 10 years ago

the loader should behave like the Java OSGI classloader