HorseAJ86 / node-jquery

jQuery with a thin wrapper for Ender.JS, Node.JS, and other npm-based packaging systems
http://jquery.com
MIT License
431 stars 66 forks source link

The state and future of the jquery npm package(s) #59

Closed coolaj86 closed 10 years ago

coolaj86 commented 11 years ago

This is a discussion that started Dec 26th 2012 and has slowly continued intermittently to the present. I felt that it was appropriate to bring it into the open for all those confused about the state and future of the package and it's relation to me, the jQuery team, and the node team.

From @isaacs

Hey, guys.

Domenic asked recently on twitter why it is that both "jquery" and "jQuery" on npm are jsdom-dependent things, and not actually jQuery. There's also jquery-browser, jqueryify, jquery-browserify, etc., which are all basically the same thing.

There are several browser libs in npm already, and it seems odd that jquery is not one of them (without requiring jsdom). Also, browserified client-side libs shouldn't really need their own thing if the lib in question exposes a node-like module interface.

How would you all feel about the jquery core team maintaining this package in npm?

All that would have to be added to jquery to make this work would be a minimal shim (something like the requirejs bits near the botom, but assigning $ to module.exports) and to replace the word "window" on the last line with "this" (which would be the same in all browsers, but also work in node.)

coolaj86 commented 11 years ago

From @treasonx:

The npm module "jquery" (very confusing all the similar module names), that I am maintaining wraps jsdom so that it can be used for DOM manipulation in the node environment. My primary use case was testing scraping logic I use in production. Basically I will scrape many thousands of static html files and analyze the output to make sure my results are sane.

I have stopped using jquery + jsdom due to jsdom being buggy, and jsdom also seems to leak memory if used in a long running process. I have switched over to using Cheerio https://github.com/MatthewMueller/cheerio which is much faster and more stable than jQuery + JSDom.

It seems like most of the users who come to the jquery npm module seem to be new to nodejs and are exploring with the familiar jquery API. Other users are using it for scraping like i was.

I would be willing to give up the module name. If we can answer some of the following concerns.

1) As long as AJ is okay with it.. He was the original author of the module.

2) There are links pointing to the module. https://www.google.com/search?q=nodejs+jquery+api How should we communicate the change to pages linking to the existing module? I am thinking mainly along the lines of stackoverflow questions, it kinda stinks to find an answer on stackoverflow only to find the library or module that was mentioned is no longer around.

3) There are lots of dependencies in jQuery on a Browser environment (document, window, XMLHttpRequest, etc) How is making jquery run in the node environment without something like JSDom benefit anyone? Or is the plan to just add jquery as a browser library to NPM?

coolaj86 commented 11 years ago

From @kapouer

Hi, great !

I did jquery-browser (as well as some other *-browser) package to ensure there was :

So really nothing smart nor fancy in that. I will remove jquery-browser when possible.

coolaj86 commented 11 years ago

From @isaacs

James,

I think those are all reasonable concerns.

As for the StackOverflow and other sites pointing to outdated info, there's not much we can do about that. There will always be outdated info out there, it's just a fact of life. People still occasionally ask why the npm bundle command doesn't work, and insist that they've already updated to the latest in their distro's package manager (which is version 0.2.9.) The only solution is to keep moving forward and improving things, and answering the questions that come up, I think.

3) There are lots of dependencies in jQuery on a Browser environment (document, window, XMLHttpRequest, etc) How is making jquery run in the node environment without something like JSDom benefit anyone? Or is the plan to just add jquery as a browser library to NPM?

The window object is mostly just a pointer to the global, but yeah, a lot of stuff won't work out of the box. I think that's fine. The jQuery package should just be jQuery, not jQuery + a web browser. If someone wants to use it with jsdom (or some other dom impl), or in browserify, or component, or bower, etc., then we should make it look just like any other npm package, so that it's a consistent interface, in my opinion.

Glad to hear there's no major objections so far. In related news: https://github.com/jquery/jquery/pull/1103

coolaj86 commented 11 years ago

From @coolaj86

I'm all for giving the module up to the jQuery team. I was just thinking yesterday how surprising it is that none of them has contacted me about it (or if they did I missed the e-mail).

However, I think that if they're going to put it on npm they need to document how to go about replacing window, XMLHttpRequest, etc.

Also, I think that jQuery should refer to a package that can be reasonably used in node. browserify, ender, pakmanager, and requirejs, as I understand, all have mechanisms whereby a package such as jquery-browser can be aliased as jQuery for the purpose of tooling / building / packaging.

I'm in the processes of moving some things I had been doing with ender/jeesh back over to jQuery (now that jQuery has been modularized), so I may have more opinions on the matter then.

As a matter of etiquette we could contact the authors of modules which depend on the various jQuery modules and give them a few weeks notice (maybe along with an annoying message each time the module is npm installed) before ripping anything out from under them.

coolaj86 commented 11 years ago

From @rwldrn

in response to @isaacs about window object:

This was my understanding as well.

In response to @coolaj86 about jQuery refering to a package that works in node and browser:

The point of this is to offer "just jQuery", and let someone else maintain a mutant version. Isaac has a PR already in for adding module.exports = ...

In response to @coolaj86 about giving authors some warning about upcoming changes:

I agree.

coolaj86 commented 11 years ago

From @treasonx

I would love to be able to call a jQuery constructor and provide the dependencies for it to use. This would be useful in the browser as well. In the case where you dynamically construct a same domain iframe it would be nice to tell jquery, "hey here is a new window and document give me a fresh jquery". In the node environment we could give it a DOM like object such as JSDom.

I looked into this before and I think we would need something like "new jQuery.fn.init" but somehow get a new instance.

In the case of pages pointing to the existing jquery module we could just leave the github project and provide instructions in the readme for setting up jquery with JSDom.

coolaj86 commented 11 years ago

From @domenic

It's not worth rearchitecting jQuery to support non-browser environments. (Not to mention I'm sure the jQuery team has no interest in this.) The correct way to use jQuery on a server is to sandbox it inside a browser environment, using e.g. the vm module + jsdom.

The benefit of a change like this comes for the growing population of people trying to use CommonJS in the browser, and more importantly, trying to use npm as our browser package manager. For the latter goal, we don't need jQuery modified at all---we just need jQuery in npm, up to date and maintained. For the former goal, we need the minimal module.exports = $ patch that Isaac pull-requested.

The fundamental disconnect, I think, comes from assuming npm is only for packages that run on the server, and thus if jQuery is to go in npm, you should somehow include a browser-on-the-server environment. By this is not true at all. There is a ton of code in npm that works great in both the browser and the server (especially with minimal shims like those provided by browserify). Many browser-based projects these days leverage that fact.

coolaj86 commented 11 years ago

From @coolaj86

I agree with this. It could be used by the browser and the server this way with minimal changes.

jQuery is now part of the larger JavaScript ecosystem, not just the browser ecosystem.

P.S. Merry Christmas / Hanukkah / Kwanzaa / Holiday / Agnostic Winter Awareness Week / etc.

coolaj86 commented 11 years ago

From @domenic

Where does the jQuery team stand on this, after meeting? I noticed Isaac’s pull request has some feedback he hasn’t quite incorporated, but I’m happy to fix that up and save him the time if the jQuery team is willing to publish to npm once a corrected version is merged.

coolaj86 commented 11 years ago

From @rwldrn

That's the plan!

coolaj86 commented 11 years ago

From @coolaj86

I see that the package has been handed off to the jQuery team. https://npmjs.org/package/jquery

However, the package on npm is actually based on my repo and I don't have the power to push updates to it. Meanwhile I've got regular pull requests, issues, and comments coming in. https://github.com/coolaj86/node-jquery/issues/

Any ETA on when the real deal will get pushed? https://github.com/jquery/jquery/blob/master/package.json

Proposal

I'd love to push a final 1.x package to, jQuery and jquery with something like console.warn('[Deprecated] Update to official jquery or use old-jquery-wrapper or old-jQuery-wrapper')

Now that jQuery has breached 2.x it's acceptable to break backwards compatibility of the npm module and move forward with just one canonical version.

P.S. I know there's some confusion as to what the 'jquery' and 'jQuery' packages are on NPM, so for the sake of clearing that up...

jQuery (capital 'Q') was for CommonJS in the browser jquery (lowercase 'q') was for Node (needing jsdom and xmlhttprequest)

Despite a few false rumors, it's nothing fancy. Straight unmodified jquery source except for adding header and footer to support commonjs and shim the missing libs.

I'm of the opinion that the jquery package should not exist because the library name is, in fact, jQuery. I made require('jquery') because the shim worked better in the browser with the capital Q due to that commonjs browser implementations often load modules from the global window object whereas jquery was not common to load in node at all.

coolaj86 commented 11 years ago

From @isaacs

Module names on npm should always be lowercase. There are a few instances (such as jQuery) where an upper-case package name was grandfathered in. But that one should definitely go away.

Rick, any ETA on a official jQuery publish?

coolaj86 commented 11 years ago

From @coolaj86

My argument for allowing packages with mixed case is that historically jQuery and some other browser modules have attached themselves to the global as a mixed case (or even all caps) name.

For the node code to also work in the browser with CommonJS and RequireJS loaders it will be easiest to keep those names cased the same.

coolaj86 commented 11 years ago

@isaacs

Why is it easiest to keep the names cased the same for RequireJS?

Node is the only CommonJS platform that matters. The CommonJS movement is over; its purpose was to find Node. The motivation to keep making JavaScript platforms more "Common" continues in ES6.

And, anyway, in any commonjs platform, you can do:

var jQuery = require('jquery');

Mixed-case folder names are a recipe for trouble, since operating systems split about 50/50 on their fs case sensitivity defaults (and it's impossible to know what kind of fs you're using just by looking at the OS!)

coolaj86 commented 11 years ago

From @coolaj86

I agree that there should not be multiple packages of difference cases.

Where it's easier is if a browser package has jQuery loaded in a script tag - for caching, convenience, or whatever reason, then window.jQuery already exists and when (some) loaders fail to find a dependency named 'jQuery' in it's internal hash, they then look at window[moduleName] before throwing an exception.

coolaj86 commented 11 years ago

From @coolaj86

I've copied all of these messages into https://github.com/coolaj86/node-jquery/issues/59 because so many people contact me asking me when the package will be updated and patches, etc.

I suggest that we continue it there (or another public forum) so that interested parties can follow along.

johnaschroeder commented 11 years ago

Thanks for clarifying the current status of the project. A couple of quick observations. First, both client and server-side developers have a stake in the jquery npm package, and while it may help push npm as a client-side package manager there are still plenty of node.js users with a variety of use cases for jQuery on node.

FWIW jsdom is definitely slow and I also tried cheerio. Cheerio is easy and much faster, but missed a few quirky selector replacements that work perfectly in jQuery. I can live with the speed hit and jsdom is continues to improve. I can't live with missing selectors. To be fair, Cheerio clearly states it will not solve all your problems - fair enough. The convenience of having a package that wraps jsdom and jquery is really helpful and appreciated. I'd love to see that functionality continue to be available, and hope that 2.0 would still support it in some fashion.

As a side note, vm may be the long term answer but it is marked unstable in the node docs: "The vm module has many known issues and edge cases. If you run into issues or unexpected behavior, please consult the open issues on GitHub. Some of the biggest problems are described below." That doesn't sound ready for prime time either.

medikoo commented 11 years ago

That's right, current configuration jquery package is quite disappointing

Problem is that it was build thinking just of server-side, while today NPM is also used for client-side package management.

What happens is, that people do npm install jquery, then they're trying to require it for their client side program (bundled with Browserify, Webmake or something else), and they're surprised to see that it tries to require all jsdom stuff and additionally they get errors like that: medikoo/modules-webmake#28

That's far from good. jquery package should be plain jQuery configured as CJS module.

medikoo commented 11 years ago

.. and devs are trying to help themselves by creating packages like jquery-untouched

kapouer commented 11 years ago

@medikoo that's the reason i'm maintaining non-minified copies in jquery-browser package. Also note that require.resolve('jquery-browser') + '/lib/jquery.js' gives the path to the actual file.

medikoo commented 11 years ago

@kapouer main point of this issue is, that jquery package should be the plain jQuery one.

Making packages jquery-browser, jquery-server etc. is bad, not generic way. There should be just jquery package which should be ready to run in any environment that implements ECMAScript3 + HTML DOM + CSSOM, that's it

coolaj86 commented 11 years ago

@medikoo disagree. it's npm. priority 1 is node, is it not?

It's much easier to specify in pakmanager or browserify that a bundled package should be aliased as something else (jquery-browser as jQuery) than for a node package to be aliased (jquery-node as jquery).

Ideally, however, jQuery should be exported in such a way that it works equally well in all javascript environments - perhaps as simple as adding an optional $.init(window); that allowed the node crowed to specify which window module to use.

medikoo commented 11 years ago

@medikoo disagree. it's npm. priority 1 is node, is it not?

Node environment is indeed primary use case, but NPM is not just package manager just for Node, and it's desirable that packages that do not depend on Node.js API can be consumed in any enviroment that implements API's they were designed for.

It's much easier to specify in pakmanager or browserify that a bundled package should be aliased as something else (jquery-browser as jQuery) than for a node package to be aliased (jquery-node as jquery).

I have received many issues in Webmake, which prove that it's opposite. Everybody expects npm install jquery to install jQuery, devs are surprised it's not exactly that. What you propose introduces not needed complexity and it's unintuitive.

Ideally, however, jQuery should be exported in such a way that it works equally well in all javascript environments - perhaps as simple as adding an optional $.init(window); that allowed the node crowed to specify which window module to use.

It should be exported in good CJS style: module.exports = jquery, and definitely should not be exposed on global namespace. NPM is only for CJS/Node.js style modules, if you're publishing something that's not that you're breaking NPM.

feross commented 11 years ago

What is the status of this? Are the jQuery devs still planning to take over this? What is the timeframe?

domenic commented 11 years ago

I've heard from @timmywil that the next jQuery release will be on npm. I assume that means the next official jQuery release, as jQuery 2.1 beta 1 is not on npm :(

abernier commented 11 years ago

@domenic will you post here when jQuery is on npm? thx ;)

mgol commented 11 years ago

@abernier if you want this information, just subscribe to the jQuery ticket: http://bugs.jquery.com/ticket/13119. We'll close it when it lands.

mgol commented 10 years ago

We've just published 2.1.0-beta2 to the npm jquery package. Please, test it guys and report potential issues to http://bugs.jquery.com so that we can publish a flawless final 2.1.0!

timmywil commented 10 years ago

As you know, this is a beta release, so npm install jquery will not get the beta package. Run npm install jquery@2.1.0-beta2.

medikoo commented 10 years ago

Something's not right:

test.js:

var jQuery = require('jquery');
$ npm install jquery@2.1.0-beta2
npm http GET https://registry.npmjs.org/jquery/2.1.0-beta2
npm http 200 https://registry.npmjs.org/jquery/2.1.0-beta2
npm http GET https://registry.npmjs.org/jquery/-/jquery-2.1.0-beta2.tgz
npm http 200 https://registry.npmjs.org/jquery/-/jquery-2.1.0-beta2.tgz
jquery@2.1.0-beta2 node_modules/jquery

$ node test.js 

module.js:340
    throw err;
          ^
Error: Cannot find module 'jquery'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/Users/medikoo/Projects/test-jquery/test.js:3:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Looking at package content, I see there's no main script configured, so it can't work.

domenic commented 10 years ago

Yeah, I filed a couple bugs:

mgol commented 10 years ago

@domenic Since the next beta won't happen incredibly soon and it's impossible to install the jquery package by pointing it to the master branch in the repo, could you try checking out the 2.1.0-beta2 commit and applying those 2 patches: 1) https://github.com/jquery/jquery/commit/6fde9752599f035da5e328b54a1e23e075e4ad45 2) https://github.com/jquery/jquery/commit/8f7db68cbf1cdc3677d89dc1191bc50c8d47a82f and see if there's anything else we should fix?

If not, the next beta should be OK to use.

mgol commented 10 years ago

@medikoo It'll be fixed in the final version. For now, you can use this form with the beta:

var jQuery = require('jquery/dist/jquery')(window);
chevett commented 10 years ago

I'm still seeing a global jQuery.

npm install jquery@2.1.0-beta2
var $ = require('jquery/dist/jquery')(window);
$(function(){
    console.log(!!window.jQuery); // logs true
});

browserify the above and check the console. http://bugs.jquery.com/ticket/14581

hustcer commented 10 years ago

I'm waiting for the final release of jQuery 2.1 of npm version.

chevett commented 10 years ago

http://bugs.jquery.com/ticket/14581 was closed as 'not a bug'. It is intended behavior for the jquery module to register global jQuery and $ variables. sad face.