BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.67k stars 339 forks source link

Error when initializing with local jQuery when jQuery is present globally #344

Closed btsvennes closed 5 years ago

btsvennes commented 5 years ago

jsRender doesn't work when using require('jsrender')($) when there is a globally defined $. The result from this call seems to be a selector to the document-element. Once i remove the ($) call (giving requrie('jsrender') everything works fine. If I remove jQuery from the global namespace, the syntax require('jsrender')($) works as expected.

Using version 1.0.2 of jsrender.

Regards, Bjørn Terje Svennes

BorisMoore commented 5 years ago

I assume that your scenario is not with Node.js on the server, but in the browser (since you talk about globally defined $). Are you using Webpack, or Browserify? If not, then I am not sure where the require() API is coming from.

In Webpack or Browserify, then what you describe is by design. You should use require('jsrender') if $ is defined globally, or require('jsrender')($) if it is not.

See https://www.jsviews.com/#node/browserify@jsrender and https://www.jsviews.com/#node/webpack@jsrender

If you have a local copy of jQuery, $, but there is also a global one, and you want to use the local one rather than the global one, you can temporarily hide the global one, as is done in this unit test, for example:

https://github.com/BorisMoore/jsrender/blob/master/test/browserify/2-unit-tests.js#L14

BTW did you see a change in behavior between v1.0.2 and previous versions v1.0.1 or v1.0.0?

btsvennes commented 5 years ago

Not my strong side, but I believe we're using Node.js to build the bundle.js-file in a Gulp-task.

I've now added a check to see if there is a global jQuery. If not I call the result of require('jsrender') with jQuery as parameter.

There was no change in behavior between v1.0.2 and v1.0.0 (I actually upgraded to v1.0.2 to check if the "error" disappeared).

As a conclusion; I need to check if there is a global jQuery or not and take actions accordingly. Would be nice if the jsrender-library handled this (for instance by ignoring the call with jQuery as parameter if a global jQuery existed).

Forgot to mention; cudos for a great template-library. Thank you very much.

BorisMoore commented 5 years ago

If jQuery is defined globally, then require('jsrender') returns the global jQuery object. If not then it returns a function to which you can pass a local jQuery object, or call without parameter to use jsrender without jQuery, (in which case it returns the jsrender object).

So if you call require('jsrender')($) and $ is actually global, then you are calling $($). I can't intercept that code. It does not return $, so you can't use the return value - but $.templates() etc will all work correctly, and nothing has been broken. jsRender does in fact still work....

The APIs were designed to optimize the most common case, which is to simply call require('jsrender'), when $ is global. But if in your case you don't know whether $ is global, then you have to use the more complicated require('jsrender')(...) in some cases....

btsvennes commented 5 years ago

I see. Then this is not an error. Sorry for troubling you.

BorisMoore commented 5 years ago

No problem...