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

support ES6-style path mapping configuration (breaking change) #180

Closed unscriptable closed 10 years ago

unscriptable commented 11 years ago

ES6 module loaders will support path mapping, but in a very different way from current AMD loaders. Imho, it solves a few existing problems. Here's a write-up by Yehuda Katz that shows a simple example.

curl.js could provide a richer set, but in the same general format:

curl.config({
    mappings: {
        // regular AMD module
        "https://ajax.googleapis.com/jquery/1.9/jquery.min.js": "jquery",
        // CommonJS package
        "lib/backbone.js": { main: "backbone", type: "cjs1.1" },
        // AMD package
        "lib/when.js": { main: "when", type: "amd" },
        // AMD bundle written in CJS, but bundled in an AMD transport
        "app.js": { main: "bundle,main", type: "amd,cjs1.1" }
    }
});

(There's a sneak peek at the new "type" option. I'll post a github issue for that shortly.)

By supporting this format, we'll be better prepared for interop with ES6 loaders. Also: there will be less confusion about whether to use "paths", "packages", or "plugins".

Actually, I haven't put much thought into support for plugin-specific mappings and configs with this new mappings format. We definitely have some people using plugin-specific configs. I'm thinking we can add those features back in in a 0.8.1 or 0.8.2 release.

Potential problems:

  1. I don't see an easy way to specify package-specific mappings without nesting them, like this:

    "lib/wire0.10": { main: "wire", type: "amd", mappings: { "lib/when1.9.3": "when" } }

  2. Until the ES6 spec is ratified, we could conflict with it. I guess we'd have to make a breaking change.

Feedback welcome!

briancavalier commented 11 years ago

Hmmm, how does this mapping work?

"lib/when.js": { main: "when", type: "amd" }

For example, how would someone depend on when.js's delay module? What would that look like? The .js extension on the left is messing with my brain.

unscriptable commented 11 years ago

Yah. I hesitated when i added the ".js", but i think it's the right thing. The suggested ES6 mappings are opposite from the AMD spec and has some subtle differences. You put the file on the left and the ids on the right. Files don't have to be ES6, CJS, or AMD. They could be legacy global hackishness, too. I'm thinking it's pretty safe if we allow devs to skip the ".js", but I think we should include it by default in our examples.

I hijacked this "backwards" format and decided that we could put more useful info on the right. What I'm hoping is that when you see the {}, your mind says "package" instead of "module" or "bundle". So I read this line as lib/when.js points to a package whose main module is "when" (and, by default, is named "when") and has modules of the "amd" type.

Does that work?

Hm.... maybe we should have a separate "packages" config option? I am afraid the TC39 team will find a different use for object literals. Those guys obviously haven't thought through all of the config stuff and packages, yet.

unscriptable commented 10 years ago

Interesting idea, but tabling it for now.