-
Notifications
You must be signed in to change notification settings - Fork 422
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
CanJS and AMD #46
Comments
Yep. Ralph, can you take a look at this? Sent from my iPhone On May 29, 2012, at 1:24 PM, Jeff Rosereply@reply.github.com wrote:
|
If you need guidance on adding optional AMD compatibility to code, check out https://github.com/umdjs/umd |
Hey, yep. This is a good call. I'm just wondering how to support this for all the different library builds. If I recall correctly, jQuery and Dojo support an optional AMD call, but does Zepto, YUI, MooTools? I'll work on this this afternoon. |
I believe only jQuery and Dojo support it right now. YUI has it's own non-AMD loader. Zepto seems unwilling to add AMD support at this time (madrobby/zepto#342). MooTools seems to be in the middle of adding support (mootools/mootools-core#2102). That being the case, you could either not list those libraries as dependencies in your define() or make certain assumptions:
This would result in: define( "can", [ "zepto" ], function () { return can; } );
define( "can", [ "mootools" ], function () { return can; } );
define( "can", [ "yui" ], function () { return can; } ); The only other choice would be to make it configurable in some way. That is, exclude the dependency unless the developer has set a value somewhere and use that value. Doing that would open it up to developers that are not using RequireJS 2.0+ as they could set the value to include loader plugins. // Load Zepto using the WrapJS loader plugin in RequireJS < 2.0
define.amd.Zepto = "wrap!zepto"
...
var deps = [];
define.amd.Zepto && deps.push( define.amd.Zepto );
define( "can", deps, function () { return can; } ); In my example, I am bastardizing the define.amd (https://github.com/amdjs/amdjs-api/wiki/AMD#wiki-defineAmd) object a little. James Burke (@jrburke) might have a better suggestion. For plugins, it should not matter as they only need to list "can" as a dependency. |
Looking over my own reply, this may make more sense: // Load Zepto using the WrapJS loader plugin in RequireJS < 2.0
define.shim = define.shim || {};
define.shim.Zepto = "wrap!zepto";
...
var deps = [];
define.shim && define.shim.Zepto && deps.push( define.shim.Zepto );
define( "can", deps, function () { return can; } ); |
Some quick notes, related to upgrading existing libraries:
not this:
if (typeof define === 'function' && define.amd) {
define(['jquery'], function ($) {});
} If you need help fitting that in to your existing code, feel free to give me a pointer to where or the ideal way you would like to see it done and I can help out. Although hopefully the aforementioned umdjs/umd code templates help. For Dojo, I would try to be specific about what modules you need from it, if that is an option: define(['dojo/array', 'dojo/event'], function (array, event) {}); Not sure if those are the right module IDs but hopefully that conveys the idea. Similar for MooTools, although I am not experienced enough with that library to know. But if unsure, if they export one single object that has the methods you need: define(['mootools'], function (mootools) {}); |
@jrburke Thanks for the suggestions! Your insight is super helpful. Why should we not used name modules? I thought this was so people could have multiple modules in the same file. When would be the appropriate time to use named modules? For Zepto, we have a bunch of additional modifications to add features that jQuery supports. I'm not sure if knowing that changes anything ... Thanks again! |
@justinbmeyer some notes here about anonymous modules: https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon but basically it is more flexible. For Zepto, it may make sense to do: define(['zepto'], function ($) {}); if you add things specifically to zepto. RequireJS users can map 'zepto' to 'jquery' if they end up somehow with the zepto version of canjs in their jquery-based project. But in that case, you may want to feature detect any additions to the $ object or be sure the changes are non-destructive. Or, just tell them to swap out the canjs with the jquery one. That seems reasonable too. |
Thanks, James. The reason for doing... define( 'can', [], function () {}); ... instead of doing... define([], function () {}); ... is that there is no single CanJS core. CanJS sits on top of various libraries, e.g. jQuery, MooTools, etc. If the module was anonymous, you would end up with a core module that has different names, .e.g. "can.jquery", "can.mootools", etc. unless you rename the core file you decide to use. For the sake of CanJS plugins, I would think there needs to be a single, core "can" module. I think hiding Zepto as jQuery is definitely the way to go. |
@jeffrose by impression though is that only one can.* is used in a project at a time, so it is OK if they are anonymous. Also any module ID that is used for a named module should match the file name by default. But I'm still new to the expectations around the use of canjs. |
One thing I've been thinking about is letting people require only the parts of canjs they need. The project is already broken up like this. For example,
But i'd still like people to be able to
|
@justinbmeyer there can be a top level can.js file that does all of those require calls and exports a module for those values: define(function (require) {
return {
control: require('can/control'),
model: require('can/model'),
ejs: require('can/view/ejs'),
route: require('can/route')
};
}); So if they want the whole thing, require 'can' instead of 'can/control'. |
This issue has certainly grown bigger than I expected, though I am encouraged by the direction, i.e. being able require individual modules as well as CanJS as a whole. I understand this isn't a priority compared to other issues but I was wondering if there was a plan of attack? Is this something we would see in the next release? |
As part of this effort, it would be nice to see can/util/zepto/fill (and similar) broken up into separate files, like can/util/zepto/fill/promise, can/util/zepto/fill/ajax, etc. This would provide the flexibility of letting developers choose how to fill those gaps. For instance, using whenjs for promises. |
I'm not sure that would help as they wouldn't be present on can. You'd hace to create your own to map to the can object. Btw, deferred is a separate file. And outside deferred, there's little that could be swapped. And, we wouldn't want these things in zepto probably, but in can/util directly so they can be used by other base libraries. Sent from my iPhone On Aug 12, 2012, at 5:17 PM, Jeff Rose notifications@github.com wrote:
|
Yes, I was thinking you would create your own mapping in the RequireJS config to swap in the implementation you want to use for whatever can was expecting. Ah, I see Deferred in can/util/deferred but I see the same code in can/util/zepto/fill (along with other code). I have to assume that can/util/zepto/fill must be built from multiple other files. I do agree that outside of something common like Promises and maybe some language polyfill (e.g. an implementation of Array.reduce), there's little that could be swapped. Yup, I was just using can/util/zepto/fill as an example. |
Hi, will this issue be resolved in the next release? |
+1 |
1 similar comment
+1 |
+1, and Bump. What is the status of AMD support now? |
I would really like to know the status of this as well. Will AMD support make it for 1.1 ? |
The version 1.1.0 download contains an |
Currently CanJS seems to have incomplete support for AMD. The core files, e.g. can.jquery.js, define themselves if an AMD loader is present.
However they do not set any dependencies. For libraries that support AMD, e.g. jquery, dojo, etc., the core files should list them as such.
Otherwise it becomes necessary to do a workaround to make sure the dependent library is loaded before loading canjs.
Similarly, canjs plugins need to register themselves as AMD modules which depend on the core canjs module.
-Jeff
The text was updated successfully, but these errors were encountered: