vakata / jstree

jquery tree plugin
http://jstree.com
MIT License
5.14k stars 1.38k forks source link

jsTree and Browserify #1275

Closed JosefWN closed 8 years ago

JosefWN commented 8 years ago

Previously (v.3.1.1) I have used jsTree with Browserify as such: require('jstree'). Unfortunately, this behavior broke in v.3.2.0. A patch was released that fixed it, but it's back again in v3.2.1.

Browserify runs just fine and includes some jsTree code, but I get an error: Uncaught TypeError: $(...).jstree is not a function.

I can downgrade to 3.2.0 and it works, but I was momentarily tricked into thinking it worked with v3.2.1 as well, likely due to caching issues (I copy/pasted the trunk version of jsTree into node_modules at one point). Sorry about that. A clean download of all node_modules does show this error, rendering jsTree v3.2.1 unusable with Browserify.

vakata commented 8 years ago

Sorry, but jstree uses the default UMD pattern for jQuery modules. Maybe the problem is that you are not requiring jQuery, and only requiring jsTree? Or it could be that you have two jQuery copies in your code. The loading has not changed and the UMD pattern is still used, but keep in mind jstree will register itself inside the jQuery "namespace" - jQuery, so you can not access it directly when requiring.

Best regards, Ivan

JosefWN commented 8 years ago

Seems to have been a bug in Browserify. After upgrading I haven't had the issue.

srinathh commented 8 years ago

I ran into the same problem with jstree v3.2.1 on npm and browserify v.13.0.0 which is the latest on npm. Downgrading to jstree v3.2.0 again seems to work with the same version of browserify.

Here's how I'm importing and using jstree:

global.$ = require('jquery');
require('jstree');
$(function(){
    $("#treenode").jstree({
        "core" : {
           .........
JosefWN commented 8 years ago

Yeah, I can confirm this is the case. Issue persists in all versions up to 3.3.1 starting with 3.2.1, and has been pestering me for a year now. Can we re-open?

What does sometimes help when I upgrade is to copy the trunk into the node_modules directory, replacing the one downloaded from npm, suggesting it's a packaging issue.

This is not a novice issue, it's a large project and all other dependencies, including those dependent on jQuery, are running just fine.

vakata commented 8 years ago

OK, but can you please provide a pull request for this - I have no idea how to fix this as I do not use browserify. If it is such an issue I will simply drop official support for browserify as I have no idea how to maintain this. All I did was use a common loader, aside from that I can not help.

To sum up - can you provide an example that works?

vakata commented 8 years ago

OK, I did some testing, as stated on the site, I did this:

npm install -g browserify

I installed the dependencies:

npm install jquery
npm install jstree

Then I created a test project with a single HTML file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>

    <link rel="stylesheet" href="node_modules/jstree/dist/themes/default/style.css">
</head>
<body>
    <div id="jstree"></div>
    <script src="bundle.js"></script>
</body>
</html>

And a single js file:

jquery = require('jquery');
require('jstree');

jquery('#jstree').jstree({ core : { data : ['Root'] } });

After that I executed:

browserify main.js -o bundle.js

After that I get a nicely rendered tree. I have never used browserify, so maybe this is way too simple, but it works for me. Please do tell which of the above did not work for you?

JosefWN commented 8 years ago

Thanks for the quick feedback. Yeah, it seems tricky to debug. I'll try to upgrade to 3.2.1, then gradually downgrade to 3.2.0 file by file, until it works. Then at least we'll have isolated it to a specific file.

Not that I think it matters, but I'm on OS X 10.11, latest versions of npm, jstree and jQuery.

Other potential culprits: ReactJS, minifyify. Do you use any of them too, @srinathh?

I'm requiring it similarly, example:

'use strict';
global.$ = require('jquery');
global.jQuery = global.$;
global.React = require('react');
global.ReactDOM = require('react-dom');
global.PureRenderMixin = require('react-addons-pure-render-mixin');

global.ReactRouter = require('react-router');
global.hashHistory = global.ReactRouter.hashHistory;
global.IndexRoute = ReactRouter.IndexRoute;
global.Router = ReactRouter.Router;
global.Route = ReactRouter.Route;
global.Link = ReactRouter.Link;
global.History = ReactRouter.History;

require('ion-rangeslider');
require('jstree');
JosefWN commented 8 years ago

To reproduce the issue I tried to remove jsTree and then download it again using npm, but it didn't cause issues. What did cause issues was when I removed my entire node_modules dir, and downloaded all of my dependencies again. The order in which the deps are downloaded affects the order in the bundled JavaScript-file generated by Browserify, for some odd reason. The issue could be more pronounced when you have more deps, my project has about 20 npm deps.

The solution is, after downloading all npm dependencies, delete jstree in node_modules and re-download it using npm, otherwise the order is preserved and jsTree will not work at all, even after future updates. This is just a theory: Normally when a component depends on another, it has it included in package.json. Since jsTree depends indirectly on jQuery (without specifying it), it is possible that jQuery is somehow included by Browserify after jsTree (even though it is included before in the require.js file). So, when I'm trying to use jsTree, I haven't defined jQuery.

That's not really a bug though, I wouldn't want each jQuery plugin to download a separate instance of jQuery, but it's good to be aware of. Why it used to work in 3.2.0 is beyond me though.

vakata commented 8 years ago

Thank you for taking the time to debug this.

As it is there is nothing I can do, but let me know if something comes up and I can improve on this situation in any way.

Best regards, Ivan

kailshar commented 8 years ago

@Puffton : Are you using jstree with ReactJS. If yes, it would be great if you can share some code snippet on how to make this react + jstree together work and manipulate dom in reactish way?

Looking forward to your response.