Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hierarchical module loading #245

Open
jbadeau opened this issue Jan 7, 2014 · 5 comments
Open

Hierarchical module loading #245

jbadeau opened this issue Jan 7, 2014 · 5 comments

Comments

@jbadeau
Copy link

jbadeau commented Jan 7, 2014

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
Copy link
Member

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
Copy link
Author

jbadeau commented Jan 8, 2014

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
Copy link
Member

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
Copy link
Author

jbadeau commented Jan 24, 2014

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

  • get its own config
  • not share the same dependency instances even if the same version unless declared as a dependency

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

  • first look for it in the root/parent config
  • then look in one of the dependency bundles config
  • then look in bundle's own config
  • if no when.js module between version [1.5.0,2] is found then a ModulNotFoundException is thrown

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
Copy link
Author

jbadeau commented Jan 24, 2014

the loader should behave like the Java OSGI classloader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants