Thanks for the clarification. There was a message Kris Kowal sent a
while back that reminded me there are some cultural differences with
the founders/early members of the ServerJS/CommonJS list and the
supporters of AMD.
The CommonJS founders wanted to work out a module syntax that could be
implemented in existing JavaScript but may not work most optimally in
the browser, with the hope that some pathways would be possible for it
to be used in the browser and there would be some uplift in browser
technology for it to work better in the browsers in the future.
At least that is how I understand it. If I have it wrong, someone
please correct me.
The AMD folks want something that works well in the async environment
of the browser today that would also make sense in the future, because
the existing mechanisms in the browsers to support traditional
CommonJS modules were not robust enough to build large applications
that can easily be debugged and optimized for performance.
Unfortunately, the way the AMD proposal came into being was
contentious: badly named and the processes were not clear, and the
cultural differences between the two groups exacerbated the issue.
I would like to bridge the gap if possible, but I also appreciate that
some lists have a certain culture they want to keep. So if it is
preferable by the founders of this list that AMD be removed from the
CommonJS wiki, I am open to it. It is preferable to have two groups
being productive instead of both butting heads on one list.
However, I think it would be possible to bridge the gap.
The main technical sticking point is eager vs lazy dependency
evaluation. CommonJS modules 1.1 do lazy evaluation. AMD uses eager
evaluation.
The patterns that lazy evaluation encourage with computed dependencies
are hazardous in async environments like the browser, where a
callback-style require call is best to use for those cases. Eager
evaluation is a more terse API for a callback-style require too.
ES Harmony Modules [1][2] operate more like eager evaluation, the lazy
evaluation patterns will not work with it. In addition, the Harmony
Module Loaders [3] Loader.load API looks more like the eager
evaluation style used in callback-style require calls common in AMD
loaders.
So for me, new information was gained while trying to support
traditional CommonJS modules in an async environment in the browser,
and given how harmony modules have progressed since the first CommonJS
modules APIs, it makes sense to go with eager dependency evaluation
for a wrapped format.
If the CommonJS founders feel this is not enough motivation to
consider a change, the culture of the founders is just too different,
or if they feel I and other AMD supports cannot be trusted to operate
in good faith, then it is probably best to split off the AMD work.
Although if it is an issue of good faith I would prefer to fix that,
and I am willing to take steps to rectify it.
I would like to hear from other CommonJS founders/early members, like
Kevin Dangoor, Kris Kowal, Wes Garland. I apologize if I left anyone
out, speak up if you fit in that category. If the general vibe is to
split off AMD by removing it from the CommonJS wiki and using another
list for its discussion, then I will work with the other AMD
supporters to do so.
Tom, I get the impression you were one of the early people too. Based
on your comments above, it seems you are in the "split off AMD" camp.
[1] http://wiki.ecmascript.org/doku.php?id=harmony:modules
[2] http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples
[3] http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders
James
At this time, regardless of any efforts we make to attempt
unification, and regardless of the large overlap of interested parties
in both projects, they are very different projects and housing them
under the same roof is confusing and misleading to newcomers.
RequireJS has grown its own wings and can live and grow without using
CommonJS as a buzzword. Our differences will inevitable be resolved
under Harmony; it doesn't make sense for CommonJS modules to migrate
to RequireJS or vice versa since modules will land in the language
soon. It does make sense for us to add support for define(function
(r,e,m) {}) boilerplate, but RequireJS is that and a lot more. The
overlap will have to be enough to support those few of us who need to
straddle the divide.
So, yes. I'm in favor of redirecting AMD to RequireJS.
Kris Kowal
+1
I see AMD as a subset of CommonJS. I do not need to load individual
modules into the browser as my primary criteria. That is what Harmony
modules will be for from what I understand. I only need to be AMD
wrapper and evaluation compatible which I can be within a CommonJS
environment [1].
In my view CommonJS is much more than AMD or Harmony. With the packages
and mappings specifications we are heading into the program composition
space which I believe is essential for the goals of CommonJS.
Developers not only need a way to build applications out of modules
(that is how I view AMD), they also need an ecosystem of tools and
libraries to make complex applications out of modules possible in a sane
fashion. This ecosystem is built on a few standards in the right areas:
+ modules
+ packages
+ programs
+ io
+ binary
...
== JavaScript everywhere
On a practical and immediate note. If you want to "straddle the divide",
i.e. use RequireJS modules/packages with CommonJS Modules 2 today you
can use the following project which is the result of my desire for doing
that and more:
https://github.com/pinf/loader-js
Christoph
--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
Thanks for joining the conversation and sharing your opinion.
The eventual addition of declare(function (r,e,m){}) to the
specification would be sufficient to ensure interoperability between
client and server-side loaders, ensuring that CommonJS is common. The
remaining differences between RequireJS and CommonJS formats will then
be reduced to differences in taste. At this point, it is clear that we
will have separate but overlapping communities with separate but
overlapping specifications, so separate and cross-linking homes for
those efforts is the proper way to communicate the situation to our
communities.
Folks, let's please avoid a long series of heated replies. NOur
priority in this thread is to get a show of hands. Let's let the globe
spin a bit so we can hear from Kevin, Kris, Hannes, and all.
Kris Kowal
*You* may not need to load individual modules because you are focused
on the server, but that happens to be the primary use and need at the
moment (i.e. within a client). I can entirely appreciate JS-on-the-
server (that is where I learned JS primarily) but at the same time you
can't just ignore the primary usage in favor of your own efforts,
efforts with Node (/me golf claps) notwithstanding.
Wes, I entirely agree, except for the "existing" part. CommonJS as it
stands now is a decent but immature specification;
the primary efforts
behind it have been focused on what amounts to a single application
(i.e. server-side).
I would submit that we as a community stand at a
crossroads, where there's a real effort to bring something designed
primarily for the browser into the CommonJS fold.
More practical applications of the specifications will help to refine
it, IMHO--and to date not a lot of effort has been put into that kind
of refinement in a browser environment.
I approach this whole portable JS problem from a purist perspective
which is why I resonate with CommonJS. For me, theory comes before
implementation where I find AMD puts implementation first as it
overcomes a specific problem limited to one deployment target (the browser).
In hearing the concerns about browser compatibility on this list and in
my desire to use all kinds of modules within a CommonJS environment I
have written a loader based on Wes's CommonJS Modules 2 draft (which
address browser loading) that will allow me to bridge all these gaps so
I can run 100% pure CommonJS in the browser using a very efficient
development process.
The loader is here:
https://github.com/pinf/loader-js
And a project (that runs in the browser) that is built on top of this is
here (it actually imports several packages designed to run under RequireJS):
https://github.com/cadorn/ace-extjs
I am not trying to push my work, I am asking you to take a serious look
at what is possible if you leverage all the latest CommonJS work. Sure,
it requires a development server, but this approach to writing
JavaScript applications allows me as a single developer to maintain
several complex applications running on server, in browser and in
browser extension using dozens of libraries from all over.
I don't think it is a questions of CommonJS or AMD. We need to share
information and build our respective communities ensuring there are
loaders, tooling and documentation in place to allow users to use
modules from both in the same runtime/sandbox/application. I am doing my
part in making AMD style modules available in a seamless/native fashion
within a pure CommonJS environment. As long as I can load a module and
have it work I don't care if it had to undergo a wrapping step that is
transparent to me and only required during development and at build time
so I say go ahead and write in AMD. I prefer CommonJS style modules.
Christoph
Your feedback is all over the map and contain some factual
inaccuracies. If you want better answers to why AMD or how it fits in
with the future, feel free to ask on the amd-implement or the
requirejs list.
I would appreciate if people refrain from responding to Mikeal's
specific comments as it will likely just muddy the waters. He raises a
question of relevancy that may be interesting but best discussed in a
separate thread.
As to the question at hand Mikeal seems to be a +0 based on his
relevancy comments.
I am hoping to hear from the rest of the CommonJS founders, but it
does seem like it is best to split out AMD from the CommonJS
list/wiki.
James
I am hoping to hear from the rest of the CommonJS founders, but it
does seem like it is best to split out AMD from the CommonJS
list/wiki.
For what it's worth I'm -1 on the split. It's not as though this list
is overburdened with traffic and the projects are geared at a similar
/ overlapping audience.
ES Harmony Modules [1][2] operate more like eager evaluation, the lazy
evaluation patterns will not work with it. In addition, the Harmony
Module Loaders [3] Loader.load API looks more like the eager
evaluation style used in callback-style require calls common in AMD
loaders.
I would like to hear from other CommonJS founders/early members, like
Kevin Dangoor, Kris Kowal, Wes Garland. I apologize if I left anyone
out, speak up if you fit in that category. If the general vibe is to
split off AMD by removing it from the CommonJS wiki and using another
list for its discussion, then I will work with the other AMD
supporters to do so.
The overlap is a transport/package format, not an authoring format, in
my opinion, but I don't really see it as a terrible thing if
"CommonJS" would become just that. Some people would no doubt still
write code directly in that format, but I for one would then see
CommonJS as a build target, which would allow us to define something
more elegant and boilerplate-free for authoring and local execution
(and in the process back-paddle on many of the compromises that were
made in that department with the existing Modules 1.x spec).
Chris
The discussion has profited both camps, and both have
made adjustments to cover more use cases. What neither
camp wants is to abandon its own work wholesale. Which
is where the friction seems to come from. I know which
kind of module I prefer, but I can accept that others have
different preferences. As long as I can use their modules,
and they can use mine (no module lock-in), does that matter?
I hope for what the ideal "CommonJS" implies, but for that
to come to fruition, there need to be useable API specs with
real and multi-platform implementations.
Modules are a baseline/stepping-stone for that. I admit that
it was fun implementing a loader myself, and I can see that
I am not alone in appreciating that much control over basic
infrastructure. But ultimately, it is more interesting to have
good libraries to load, offering mostly the same APIs, no
matter what platform I'm on.
James has done a great job of popularizing module loaders,
adapting his library to cover more use cases, and trying to
find consensus among different API camps. In trying to be
accommodating, he has added so many features to his library
that it is no longer the simplest loader in the game. But his
work is still an example of what bystanders like me would
like to see from CommonJS: reuseable and visible software.
Some of the CommonJS contributers build (and use, in their
own projects) a lot of useable software, but that does not
seem to translate into more generally reusable libraries/
APIs on the CommonJS list or website. Remember, that is
an outsider's view - from someone still trying to decide
whether there is something to take home from CommonJS.
> I'm flattered to hear that you think only my platform is
> worth mentioning, however besides GPSEE there is also
> Node.JS, v8cgi, Flusspferd, Narwhal, Mozilla's JetPack,
> RingoJS, Wakanda, CouchDB, Persevere, Joyent's Smart
> Platform, EJScript, and others which are seeing use in industry.
Node.JS has won the popularity contest - that doesn't mean
it is the best or only game in town, it doesn't even mean that
this popularity will last; but it does mean that people listen
when the Node.JS creator says that CommonJS is irrelevant:
http://www.reddit.com/r/node/comments/h1m2o/i_am_ryan_dahl_creator_of_nodejs_ama/c1ry6oc
Moving successful-in-practice efforts of those who _want_
to work with CommonJS to separate lists seems to be
exactly the wrong kind of response to such statements.
Claus
But ultimately, it is more interesting to have
good libraries to load, offering mostly the same APIs, no
matter what platform I'm on.
My thoughts/opinions/summary:
* Almost everyone (self included) is in favor of some form of
"asynchronous module definition" format for loading modules via script
tags.
* Many original CommonJS participants (myself included) absolutely ARE
interested in interoperability between browser and server-side
JavaScript. This is one reason the name was changed from ServerJS to
CommonJS.
* If you are in favor of AMD as an "authoring format" (I like Chris'
name for it) you are not prioritizing interoperability. AMD imposes an
implementation detail on developers that make no sense for
environments other than the browser.
* People who don't care about interoperability with non-browser
environments have no place being involved with CommonJS.
The divide here is between people who see AMD as a "transport format"
that should be generated by a build tool or server, versus an
"authoring format" that should include hand-written async definition
boilerplate.
* From what I understand the argument for AMD as an "authoring format"
boils down to this:
- Some browsers have problems reporting filename and line numbers
for exceptions and during debugging for code though "eval"/"new
Function()" that they don't have with code evaluated though script
tags.
- In some cases you might want to load a module using a script tag
without having to minify/wrap/bundle it.
* My arguments for AMD as a "transport format" (and I believe many
people agree with me) are:
- We may be stuck with this module spec for awhile (5+ years until
ECMA specs modules, browsers implement them, and the vast majority of
users upgrade?), so it should be forward-looking, not held back by
legacy issues with browsers that are rapidly going away.
- It should be suitable for both browsers and server-side environments.
- A tool or server should be used to minify, wrap, and bundle your
client-side code for deployment anyway.
- Boilerplate sucks and should not have to be written by hand. It
should be considered an implementation detail.
- The features browsers offer for asynchronously loading and
evaluating code without using script tags are "good enough" for
development, and they're improving.
- Any issues with the browsers should be considered bugs in the
browser as they are likely common problems for web developers, and
they should be fixed in the browser.
I see a few scenarios that would maximize interoperability that I'd be
happy with (in decreasing order of my happiness):
* We agree that AMD should be a transport format only. Browser loaders
like RequireJS can implement only AMD, but they should not encourage
users to hand-write the AMD boilerplate.
* We agree that implementations that implement AMD should also
implement basic CommonJS 1.x modules (or whatever the future iteration
is).
* We agree that all implementations should implement both AMD and
CommonJS 1.x modules.
Regardless of the outcome, I also think RequireJS should change their
name and/or implement CommonJS 1.x modules. I absolutely hate that it
has co-opted the name "require" and are confusing developers about
CommonJS modules.
-tom
I agree it's a travesty we can't even do a portable "hello world".
However, my opinion on which things we should be working on has
changed. We were very eager and I think we bit off more than we could
chew at the beginning, which was part of the problem.
If I were to do it again, I'd be very careful about what we worked on
and when. Starting with things that don't make too many assumptions
about the underlying platform is key.
I'd be super happy if we (*including Node*) could agree on the following:
* modules (CommonJS modules 1.1.1 are fine)
* console output (can't we all agree on "console.log" at this point?)
* fixed-length mutable binary buffers (just use Typed Arrays maybe?)
* command line arguments and environment variables (I'm split on the
global object like "process" in Node vs. a module like CommonJS's
"system")
Then I'd do synchronous file reading/writing, which even Node has.
After that there's not really anywhere to go without tackling the sync
or async IO debate (and the resulting promises vs streams vs whatever
debates). I'd like to spec both, clearly separated, but in a way that
was complementary to each other.
Also, I think test suites would be key. Platforms should declare which
specs they implement, then we could run the test suites and
automatically generate a matrix showing which platforms implement
what, and whether they're currently passing the test suite. That would
be huge.
Anyway, those are just my random thoughts. If we seriously want to
consider rebooting CommonJS's work on that stuff I have a lot more
thoughts on it.
-tom
I don't agree with this characterization. A build tool is completely
off the table for me. I would not consider any module loading scheme
that requires a build tool. So for me the divide is build too or no
build tool.
...
Any build step is unacceptable during development.
This statement is definitely a cultural one. Which is fine, and I
think a good reason to not continue detailed AMD discussion on this
list. FWIW, AMD as an authoring format works better and more
consistently across all JS environments. That is interoperability that
actually matter to developers. But again, this is a cultural
difference.
> * People who don't care about interoperability with non-browser
> environments have no place being involved with CommonJS.
Right, that seems like a no-brainer. Not sure you needed to mention it
unless you meant to imply something else about my motivations. All the
work I have done works in non-browser environments.
> The divide here is between people who see AMD as a "transport format"
> that should be generated by a build tool or server, versus an
> "authoring format" that should include hand-written async definition
> boilerplate.
So, if there is a standard transport format, it seems reasonable for
server implementations to support it too, since it also allows easy
transport of multiple modules in one file, even for use on the server.
It can be a legitimate way to pass around modules.
So if the server also understands the transport format, what does it
matter if a tool or a person authors the format?
As you indicate, having the server understand the transport format is
not the most palatable solution for you, which brings up the main
point.
My main issue is that by treating something like AMD as "just a
transport format", it makes it easy to avoid thinking about the real
issues with async loading in the browser, no matter if there are
special tools/upgrades in the browser to handle them.
Like the issues with lazy evaluation, and how that also affects a
callback-style of require, where it seems silly to use lazy evaluation
for that kind of callback API. The direction of harmony modules is a
data point that confirms this.
You can hope the transport format is just a patch until better
capabilities come in the browser, but those better things will likely
just be harmony modules support. So the implementation choice for
today should work in today's browsers. Which also happens to work on
the server.
Anyway, flame off. This is definitely a cultural issue, and I'm fine
saying that the CommonJS list has a culture that matches what you
outlined.
> Regardless of the outcome, I also think RequireJS should change their
> name and/or implement CommonJS 1.x modules. I absolutely hate that it
> has co-opted the name "require" and are confusing developers about
> CommonJS modules.
The goal with RequireJS was to be able to provide an effective wrapper
around CommonJS module concepts. The issue with lazy vs early
dependency evaluation did not crystalize until later. For the small
number of modules that actually depend on that difference there can be
a problem, but there would likely be an issue anyway, particularly
with the computed require cases.
But the vast majority of CommonJS modules can be loaded by
AMD/RequireJS given a wrapping. I have even gone to extents to support
both module.exports and module.setExports, although at this point
setExports looks like a dead end.
CommonJS does not have special ownership of 'require'. I support the
CommonJS concept as much as it makes sense for an async environment,
and in a way that is more future compatible, so I do not plan on
changing the RequireJS name.
You'll need to get over the RequireJS name, and I'll need to get over
wishing this list had a different culture than what its name initially
implies.
So I think the next steps would be:
* Move the bulk of AMD discussions to another list.
* Copy the AMD API that is on the CommonJS wiki to another area.
* Leave the AMD API page on the CommonJS wiki, but update it to
mention its further development is at the other place and mention the
small edge cases where it cannot handle CommonJS modules.
* Post back to this list if/when there are common concerns that might
affect both groups.
Hopefully that would be enough to assuage your concerns about AMD
causing confusion with traditional CommonJS Modules 1.1, and free this
list up to discuss other things.
James
> On May 19, 4:21 pm, Nathan Stott <nrst...@gmail.com> wrote:
>> I don't get why any build tool is off the table for development. Have
>> you never worked with a language you have to compile?
>
> Yes, a few, like Fortran, C++, C, and Java. Build tools are a relic of
> the past.
Are you saying you don't minify and concatenate your JavaScript files when you deploy client-side JavaScript? I pity your users.
> Is this really
>> such a burden? Apparently it is, but this attitude is still foreign
>> to me. I'll trade not having to write boilerplate by hand for having
>> a build step or having to run a special dev server.
>
> What boilerplate?
Question: what is the bare minimum code necessary in a JavaScript file for that file to be loaded using an AMD loader?
That is boilerplate.
> On May 19, 1:25 pm, Tom Robinson <tlrobin...@gmail.com> wrote:
>> * If you are in favor of AMD as an "authoring format" (I like Chris'
>> name for it) you are not prioritizing interoperability. AMD imposes an
>> implementation detail on developers that make no sense for
>> environments other than the browser.
>
> I'm unclear on what implementation detail you mean here.
> ...
Wrapping modules in an anonymous function that gets passed to another function is 100% an artifact of the requirement that you be able to use script tags to load lazily executed modules. Fact.
Show me one other language that does anything remotely similar.
>> - The features browsers offer for asynchronously loading and
>> evaluating code without using script tags are "good enough" for
>> development, and they're improving.
>
> Script tags are implementation detail. I ported require.js AMD to
> Mozilla gecko using evalInSandbox and it would have worked if the
> Mozilla platform worked.
Of course you *can* implemented AMD without script tags, but as mentioned above, AMD was designed specifically for the script tag use case.
>> - Any issues with the browsers should be considered bugs in the
>> browser as they are likely common problems for web developers, and
>> they should be fixed in the browser.
>
> Yay, something to agree on!
I'm saying any issues with using XHR+eval are browser issues, not spec issues. I don't suspect you'd agree with that.
> ....
>> Regardless of the outcome, I also think RequireJS should change their
>> name and/or implement CommonJS 1.x modules. I absolutely hate that it
>> has co-opted the name "require" and are confusing developers about
>> CommonJS modules.
>
> Ironically we use AMD and don't need the word "require" at all. So
> here I agree!
Great! Change it to define.js or whatever.
-tom