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

Add AMD to Zepto #342

Closed
wants to merge 1 commit into from
Closed

Add AMD to Zepto #342

wants to merge 1 commit into from

Conversation

Filirom1
Copy link

Very usefull, when we want to choose between Jquery or Zepto on the client side:

define.amd.jQuery = true;

define([
  RegExp(" AppleWebKit/").test(navigator.userAgent)? 'zepto' : 'jquery'
], function($){
  $(function(){
    $('#main').text('Hello World !!!');
  });
});

Very usefull, when we want to choose between Jquery or Zepto on the client side: 

    define.amd.jQuery = true;
    
    define([
      RegExp(" AppleWebKit/").test(navigator.userAgent)? 'zepto' : 'jquery'
    ], function($){
      $(function(){
        $('#main').text('Hello World !!!');
      });
    });
@mislav
Copy link
Collaborator

mislav commented Nov 26, 2011

Never heard of it. I don't think we'll bother with this until (if?) AMD gets wide adoption.

@Filirom1
Copy link
Author

Never heard of it ?

There is short online presentation here, that give the main idea of what AMD is :
http://www.tagneto.org/talks/jQueryRequireJS/jQueryRequireJS.pdf

And a longer and very interesting one by Addy Osmni here :
http://addyosmani.com/writing-modular-js/

AMD helped me a lot to structure single page web app.
Even if you don't integrate this pull request, take a look at RequireJs or curl.js implementation. There is also almond, which is designed for mobile, that could interest you.

RequireJs : http://requirejs.org/
Curl.js : https://github.com/unscriptable/curl
Almond : http://tagneto.blogspot.com/2011/08/almond-small-amd-shim-loader.html

I am quite found of the text and the i18n plugin. Very useful for building single page web app which need to render templates on the client side.

Jquery [1], UnderscoreJS[2], Dojo[3] are some well known libraries that are AMD compatible.

[1] https://github.com/jquery/jquery/blob/master/src/exports.js#L18
[2] https://github.com/documentcloud/underscore/blob/master/underscore.js#L50
[3] http://dojotoolkit.org/features/1.6/async-modules

Have a nice reading :)

Cheers
Romain

@mislav
Copy link
Collaborator

mislav commented Nov 26, 2011

I'm down with CommonJS exports ala underscore.js, and if we can add AMD support in a single line more that's fine with me.

But the 10 line comment on jQuery AMD integration freaks me out because I don't understand a word of it.

@jrburke
Copy link

jrburke commented Nov 27, 2011

I worked on the jQuery commit, and they had very specialized concerns. I can go into more detail if you like, but for Zepto, the following is the standard way to register as an AMD module, and it is the right signature for Zepto:

    if (typeof define === 'function' && define.amd) {
      define(function() { return Zepto; });
    }

@jrburke
Copy link

jrburke commented Dec 1, 2011

I saw a tweet from @mislav about reading up on script loaders and not liking what he saw. Here is a bit more context about AMD and how it relates to Zepto:

AMD is about defining modular code for JS that works well natively in browsers. Since the browser does not have a natively supported module API, AMD implementations usually include a script loader, although that is not a requirement.

The almond AMD API shim just provides the module API, but assumes all the modules have been built into one file. This is a great option to use for deploying code after using a dynamic script loader during development to get individual file loading for easy debugging.

However, if you never want to deal with a script loader even in development, you can use almond and deliver on-demand HTTP builds of your code.

AMD is focused on avoiding globals, and since it supports anonymous modules, and ways to map the anonymous modules to different names, it means in this particular case that Zepto can be swapped in for the 'jquery' dependency name, without requiring higher level libraries to change their code to explicitly look for Zepto.

This has come up in Backbone. Backbone will likely support optional AMD registration in its next version so this means that any AMD-based project that wants to use Zepto instead of jQuery just needs to map 'jquery': 'zepto', and as long as Zepto uses the anonymous define() call I suggested, it just works out.

So the end result -- as more libraries have opt-in support for AMD, it means Zepto is easier to use in place of jQuery. Since almond can be used with a function wrapping over the built code, it means smaller libs can use Zepto as part of their internal structure, but not have to worry about global collisons with other code on the page.

I did a post responding to some concerns Jeremy Ashkenas had about AMD, which also might be useful.

@madrobby
Copy link
Owner

madrobby commented Dec 4, 2011

This can be added as an add-on if required, but Zepto shouldn't make any assumptions about how someone wants to load it.

For Zepto 1.0 we're planning on a web-site based tool (and a command-line based one) to construct your own Zepto distribution (without any additional JavaScript required), which will be our recommended way to include it.

@madrobby madrobby closed this Dec 4, 2011
@mislav
Copy link
Collaborator

mislav commented Dec 4, 2011

Yeah I too changed my mind about adding CommonJS exports to Zepto. They would be mostly useful server-side, like in Node, but there's no DOM server-side so Zepto becomes kinda useless.

@jrburke: To explain my negative commens about JS loaders: First, there's too many of them. Each new one is created because "all others suck and/or are too bloated", as they often state in their README. Second, there's no scientific proof that they really speed up load times as opposed to one big concatenated+minified script. They help you "organize your code", but my code is already organized. Third, they are usually huge (almost the size of Zepto) and the amount of documentation for popular ones is overwhelming (aren't they supposed to be simple?). And lastly, some of the most popular ones provide some kind of a server-side tool to concatenate+minify all scripts together in one big file to serve in production. What's the purpose of a JS loader then?

I come from Ruby world and in Ruby world of web apps we have this: you start building your app. You write your JS in separate ".js" or ".coffee" files. In development they are loaded separately, but in production they are concatenated into one minified script. There's no thought or decision-making involved in this, it just works by magic. So you see why we aren't easily impressed with loaders.

Everybody (like you) just advocates the loader/module pattern that they are involved with, but I don't see any developers who I know are building real apps advocate them. Whenever I try to learn about them (I read most of the links you shared with me, and many more) I get lost in long theoretical, philosophical discussions on mailing lists in which there seems to be no general concensus in the javascript community. And those discussions are all about chasing invisible ghosts and trying to solve problems which are not really problems.

@Filirom1
Copy link
Author

Filirom1 commented Dec 4, 2011

@mislav you are using rails that's why you already have good ways to
organize, merge and minify your js script.

I don't use rails, I am creating Single Page Web App, only written in JS,
HTML and CSS. My pages could be hosted everywhere. And my server is at ease
because it don't have to worry about doing server side templating. Now that
JS is quite performant even on mobile, I am happy with this approach.

I found requireJs very useful. Not for speeding the load time (beacuse for
production I merge most of my libs), but for organizing my code. I don't
know how you handle HTML in Javascript files. But I found the RequireJS
text plugin very useful for this. Look at this dummy example :

// script file
https://github.com/Filirom1/requirejs-examples/blob/master/underscore/bootstrap.js

// html template
https://github.com/Filirom1/requirejs-examples/blob/master/underscore/tmpl.html

// dummy data
https://github.com/Filirom1/requirejs-examples/blob/master/underscore/data.js

What I love with AMD (because requireJS is not the only implementation,
there is also curl.js which is quite good too), is the dependency system.
If you use Jquery UI, it's quite boring to remember which jquery UI
component you really depend on. With AMD, dependencies are defined and
resolved properly (remember that I don't use rails, or any other asset
management). Look at this example :

// without requireJS, you must define your dependencies in the good order
https://github.com/Filirom1/requirejs-examples/blob/master/jqueryui-without-requirejs/datepicker.html#L8

https://github.com/Filirom1/requirejs-examples/blob/master/jqueryui-without-requirejs/js/bootstrap.js

//with AMD you don't have to worry about the order
https://github.com/Filirom1/requirejs-examples/blob/master/jqueryui-requirejs/datepicker.html#L9

https://github.com/Filirom1/requirejs-examples/blob/master/jqueryui-requirejs/bootstrap.js

With AMD you could do dynamic loading. As I said before, I am doing single
page web app. Often, I don't use this feature because my apps are quite
simple and in this case I prefer to only load one merged JS files.
RequireJS optimizer do it well, and the Almond implementation (<1ko) is
quite light for this job.

But sometimes, I am building bigger web apps. I don't want to load all my
scripts when the user hit the first page. But if the user access other
pages, I need more features, so I will load them dynamically with a require
call.

In the case I can use the almond implementation (no dynamic loading), so I
use the curl.js implementation which is only 5Ko

AMD and the requireJS optimizer give me ways to structure my code and
manage my assets. I am happy with it.

My happiness could be even greater if you decide to add this single line in
the Zepto code :D

if (typeof define === 'function' && define.amd) define(function() {
return Zepto; });

Cheers
Romain

2011/12/4 Mislav Marohnić <
reply@reply.github.com

Yeah I too changed my mind about adding CommonJS exports to Zepto. They
would be mostly useful server-side, like in Node, but there's no DOM
server-side so Zepto becomes kinda useless.

@jrburke: To explain my negative commens about JS loaders: First, there's
too many of them. Each new one is created because "all others suck and/or
are too bloated", as they often state in their README. Second, there's no
scientific proof that they really speed up load times as opposed to one big
concatenated+minified script. They help you "organize your code", but my
code is already organized. Third, they are usually huge (almost the
size of Zepto) and the amount of documentation for popular ones is
overwhelming (aren't they supposed to be simple?). And lastly, some of the
most popular ones provide some kind of a server-side tool to
concatenate+minify all scripts together in one big file to serve in
production. What's the purpose of a JS loader then?

I come from Ruby world and in Ruby world of web apps we have this: you
start building your app. You write your JS in separate ".js" or ".coffee"
files. In development they are loaded separately, but in production they
are concatenated into one minified script. There's no thought or
decision-making involved in this, it just works by magic. So you see why we
aren't easily impressed with loaders.

Everybody (like you) just advocates the loader/module pattern that they
are involved with, but I don't see any developers who I know are building
real apps advocate them. Whenever I try to learn about them (I read most of
the links you shared with me, and many more) I get lost in long
theoretical, philosophical discussions on mailing lists in which there
seems to be no general concensus in the javascript community. And those
discussions are all about chasing invisible ghosts and trying to solve
problems which are not really problems.


Reply to this email directly or view it on GitHub:
#342 (comment)

@arextar
Copy link
Contributor

arextar commented Dec 4, 2011

How hard would it really be to just include this yourself rather than including it in the library where it will not always be put to use?

@domenic
Copy link

domenic commented Dec 5, 2011

Never heard of it.

I wouldn't admit that in public...

Zepto shouldn't make any assumptions about how someone wants to load it.

It already does: it assumes people want to load it by manually inserting a <script /> tag into their HTML source and pulling a global variable off of the window object.

In the growing world of serious JavaScript application development, this is no longer an acceptable option. Our team at barnesandnoble.com (the digital education team) prohibits coupling code through global variables, and so to use Zepto we have to jump through some hoops to introduce the <script /> tag into our single-page application, write an exception into the build process, and then do (basically) the following:

define("zepto", window.Zepto);
delete window.Zepto;

jQuery's support of AMD, however, makes it a much more attractive option; we no longer have to add special exemptions to the build process to scan for non-modular code like Zepto, or include the above hack.

@jrburke
Copy link

jrburke commented Dec 5, 2011

@madrobby: good to know about the web site/command line builder. If an AMD wrapping for Zepto could be easily included in that, that would be great.

@mislav: Right, the point of AMD is to work out a common modular format for JS code, and it can work well in a rails environment, where all the scripts are bundled up.

Not all JavaScript development fits in the development size of a typical rails/django app, and at the larger end of the spectrum (webmail/maps-sized apps) manually ordering dependencies breaks down, and managing globals and staged loading is important. Not all JS development needs a server either, so requiring a server to prep the JS resources is not suitable.

Which is great, the JavaScript world has room for all those paths, but each can benefit from modular code JS that can be reused by the different groups. Ideally this would be in the language, but it is a bit tricky to get right in a networked-environment, and there is an opportunity to do something better with dependencies that are not pure JS. So while the ECMAScript committee is looking at modules, it is still in the early stages, and I think AMD will still be needed for a while even if they get it sorted out.

FWIW, I do not promote AMD because I just have a loader that uses it. I come from a Dojo background, and building larger JS apps. The goal of AMD is to be a multiple-implementation of a modular JS standard, and it comes out of real needs seen in other JS communities, building real apps. There is an amd-implement list for both loader implementers and library owners across projects to discuss issues. Dojo, MooTools and jQuery all recognize the value of a common standard, and with Dojo, MooTools, RequireJS, curl and a few others (like almond, which is not a script loader, just an AMD API implementation), there are enough implementations and base library conformance to feel like we are on to something. No, not all projects need a script loader, but almost all projects can take advantage of a common module API.

As mentioned previously, being able to map the AMD "jquery" dependency to Zepto gives Zepto an easier pathway into projects, without requiring all the libraries that might use it to do a (this.jQuery || this.Zepto) or force the use of $ which is historically too ambiguous.

But I understand if you do not want this code always delivered for Zepto. If there is a web builder that people can assemble their own, and an AMD call can be part of that, then that is great. Feel free to ping me if there is anything I can do to help out with that effort.

@madrobby
Copy link
Owner

madrobby commented Dec 5, 2011

Again, no, we will not add it, because it's not what most people actually do or need. Fwiw, we can't accomodate any loaders that require a source change in the stuff it loads; and recommend using a build tool that doesn't need this. There's plenty around.

Lengthy "discussions" will not change my stance on this.

@SimplGy
Copy link

SimplGy commented Mar 5, 2012

I would have found it useful, as I can load in jQuery this way and would like to conditionally choose the library.

@mislav
Copy link
Collaborator

mislav commented Aug 17, 2012

Both core team members have reached a decision: no AMD or similar "integrations". It's pointless to keep updating this ticket. As for noconflict, you can open up a separate issue outlining your needs for it, but I doubt we will consider it since Zepto is already unobtrusive (doesn't overrride window.$ if it already exists). There's no "conflict" to begin with.

@hartmannr76
Copy link

I've been looking everywhere for a solution and I really hope someone here can help me. I'm trying to use requireJS with backbone and zepto and every time I try running, require seems to be searching for a jQuery library but I dont want to use jQuery in my project. Has anyone successfully used zepto and require?

@beradrian
Copy link

Sometime extra 50kb could mean a lot. Also a lot of overhead in jquery for supporting ancient browsers.

@beradrian
Copy link

Unfortunately, jQuery2 is still beta. On the other hand, the decent zepto version is rc. So could be not be such a huge difference.
For sure I expect a final release of jQuery 2 and then this will be the way forward..

@tiye
Copy link

tiye commented Oct 11, 2013

it's not what most people actually do or need

Quite doubt if that's correct. And two years have past, more and more people are using RequireJS.

@graefen
Copy link

graefen commented Oct 11, 2013

While I agree that AMD support can be useful in certain dev environments, I commend @madrobby for trying to keep Zepto slim and not go the way of jQuery, including "everything under the sun." He has to draw the line somewhere. Many JS devs, like myself, don't use AMD-based libs because it's not needed due to our dev environment/techniques.

@beradrian
Copy link

The problem is that unlike jQuery, zepto cannot be easily integrated with AMD. But less and less people will be using zepto, now that jQuery 2 is out there.

@graefen
Copy link

graefen commented Oct 11, 2013

jQuery 2 is a nice update to jQuery, but it's still a sizable download compared to Zepto. Some people prefer jQuery, and others prefer Zepto. I myself use both, depending on the situation...different tools for different purposes!

@mainiak
Copy link

mainiak commented Oct 17, 2013

@graefen +1

@wkeese wkeese mentioned this pull request Oct 27, 2013
@madrobby
Copy link
Owner

madrobby commented Jan 5, 2014

As we said before, it's pointless to keep updating this ticket. I will delete any further comments and clean the ticket out of +1 comments in order that people that find this have an easier time reading about the reasons why we don't support this.

If you need AMD support for your project, just add a wrapper for it.

@mislav mislav mentioned this pull request Apr 10, 2014
Repository owner locked and limited conversation to collaborators Aug 20, 2014
vincentbernat added a commit to vincentbernat/dashkiosk that referenced this pull request Jun 21, 2015
I also tried to use debowerify but many components are just not
ready. Angular doesn't handle browserify correctly and needs a small
hack. Understandable as it has its own framework. Zepto is against any
loader and quite hostile (madrobby/zepto#342).

Therefore, it seems easier to leave the Bower part as is.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.