Browserify with Kendo UI

11 posts, 0 answers
  1. donbrad
    donbrad avatar
    3 posts
    Member since:
    Dec 2013

    Posted 12 Aug 2014 Link to this post

    I'm trying to set up Kendo UI with Browserify. I'm require()ing the necessary kendo components from the downloaded build (in this case js/kendo.menu.min.js), but I'm getting

    Uncaught TypeError: Cannot read property 'jQuery' of undefined kendo.menu.min.js:9

    when I call

    this.$el.kendoMenu();

    I'm using browserify-shim and grunt-browserify to build. Do I need to shim this somehow?
  2. Petyo
    Admin
    Petyo avatar
    2439 posts

    Posted 13 Aug 2014 Link to this post

    Hi,

    my guess is that the kendo.core.js file is not included correctly. The error seems to be caused by the window.kendo.jQuery reference in the menu file. 

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. donbrad
    donbrad avatar
    3 posts
    Member since:
    Dec 2013

    Posted 13 Aug 2014 in reply to Petyo Link to this post

    When I require kendo.core.js, I get a jQuery not defined error, even though I have:

    var jQuery = require('jquery');

    right above. I was able to get it to work with window.jQuery = jQuery, but this is not ideal as it makes jQuery a global.
  5. Mihai
    Admin
    Mihai avatar
    153 posts

    Posted 15 Aug 2014 Link to this post

    Hello,

    This is unsupported at this time.  Kendo relies on the global jQuery variable.

    Regards,
    Mihai
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Nathan
    Nathan avatar
    4 posts
    Member since:
    Nov 2014

    Posted 25 Nov 2014 in reply to Mihai Link to this post

    You need to use browserify-shim to setup a dependency between Kendo UI and jQuery.  I also needed to use browserify-shim to setup angular (installed angular via npm install but that won't work by default with browserify).

    Here's a snippet from my package.json. See the browserify-shim section where I'm shimming KendoUI and telling browserify it requires jquery:jQuery to exist.

    "browser": {
        "angular": "./node_modules/angular/angular.js",
        "angular-aria": "./bower_components/angular-aria/angular-aria.js",
        "angular-animate": "./bower_components/angular-animate/angular-animate.js",
        "hammer": "./bower_components/hammerjs/hammer.js",
        "angular-material": "./bower_components/angular-material/angular-material.js",
        "kendo": "./libs/kendo-ui/js/kendo.all.min.js"
      },
      "browserify": {
        "transform": [
          "browserify-shim"
        ]
      },
      "browserify-shim": {
        "angular": {
          "exports": "angular",
          "depends": "jquery"
        },
        "kendo": {
          "depends": [
            "jquery:jQuery",
            "angular"
          ]
        },
        "hammer": "Hammer",
        "angular-material": {
          "depends": [
            "angular",
            "angular-aria",
            "angular-animate",
            "hammer"
          ]
        }
      },
  7. Timothy
    Timothy avatar
    7 posts
    Member since:
    Sep 2014

    Posted 12 Dec 2014 in reply to Nathan Link to this post

    Thanks Nathan! This is very helpful.

    I installed angular (and will detail my findings below), but I am really having difficulty getting kendo to build with browserify:

    here is my package.json:
    ```
    "browser": {
    "kendo": "../../kendo-ui/kendo.all.min.js"
    },
    "browserify-shim": {
    "kendo" : {
    "depends" : ["jquery:jQuery",
    "angular"]
    }
    },
    ```

    when I do this, I get

    ```
    > watchify --debug -o js/bundle.js -v -d .

    Error: EISDIR, read
    4743321 bytes written to js/bundle.js (3.64 seconds)
    Error: Unable to find a browserify-shim config section in the package.json for /asfsadfsdant/sis-ci/sis/kendo-ui/kendo.all.min.js while parsing file: /sfsdafsadfis-ci/sis/kendo-ui/kendo.all.min.js
    ```

    What is going on here?
    any thoughts on how I can get it in?


    Here is what I did with angular.

    I am able to get Angular working without any problems doing this:

    ```
    $ npm install --save angular
    ```
    This installs the new Angular (1.3.6)

    then I had issues `requiring()` it.

    What I was trying was:

    ```
    var angular = require('angular')
    ```
    however with this method `angular` is an empty object ({})

    the correct way to do it is to just require angular:
    ```
    require('angular')
    angular.module(...
    ```
    This works!!!





  8. Timothy
    Timothy avatar
    7 posts
    Member since:
    Sep 2014

    Posted 12 Dec 2014 in reply to Timothy Link to this post

    Ok I was able to use the browserify-shim to allow angular to be imported in the usual manner just like nathan reported:

    "browser": {
    "angular" : "./node_modules/angular/angular.js",
    "kendo": "../../kendo-ui/kendo.all.min.js"
    },
    "browserify-shim": {
    "angular" : {
    "exports" : "angular",
    "depends" : ["jquery"]
    },
    "kendo" : {
    "depends" : ["jquery:jQuery",
    "angular"]
    }
    },



    kendo is still broken though =(


  9. Timothy
    Timothy avatar
    7 posts
    Member since:
    Sep 2014

    Posted 12 Dec 2014 in reply to Timothy Link to this post

    Ok I put the kendo library in the same directory and it works great now...
    I guess you can't have a path that is above the pacakge.json .

    hopefully this helps someone else.
  10. Timothy
    Timothy avatar
    7 posts
    Member since:
    Sep 2014

    Posted 12 Dec 2014 in reply to Timothy Link to this post

    OK I thought it was working great but I kendo wasn't seeing 'jQuery'

    The fix: add jquery to the browser section:

    final working ( I hope ) package.json:

    "browser": {
    "angular" : "./node_modules/angular/angular.js",
    "jquery" : "./node_modules/jquery/dist/jquery.js",
    "kendo": "./kendo-ui/kendo.all.min.js"
    },
    "browserify-shim": {
    "angular" : {
    "exports" : "angular",
    "depends" : ["jquery:jQuery"]
    },
    "kendo" : {
    "depends" : ["jquery",
    "angular"]
    }
    },

  11. Nathan
    Nathan avatar
    4 posts
    Member since:
    Nov 2014

    Posted 12 Dec 2014 in reply to Timothy Link to this post

    Timothy said:

    "browser": {
    "angular" : "./node_modules/angular/angular.js",
    "jquery" : "./node_modules/jquery/dist/jquery.js",
    "kendo": "./kendo-ui/kendo.all.min.js"
    },
    "browserify-shim": {
    "angular" : {
    "exports" : "angular",
    "depends" : ["jquery:jQuery"]
    },
    "kendo" : {
    "depends" : ["jquery",
    "angular"]
    }
    },


    Tim - I think your package.json file is a little incorrect.  First, if you install jquery via npm (npm install jquery) you don't need an entry in the "browser" field.  This field is really to identify a specific js file you want to use when you run browserify and it sees require('xxx').  If 'xxx' is installed by npm AND it's CommonJS compliant (this is the biggy!) then you can omit it from this field.  The latest versions of jquery on npm ARE CommonJS compliant so you can leave out jquery.

    Note how I say CommonJS compliant.  While AngularJS is installed via npm it is **STILL** not CommonJS compliant...why I don't know. You'd think the Angular team would do it to make everything easier.

    You do need kendo and angular in the "browser" field.

    Your browserify-shim field looks great for angular...however your entry for kendo is incorrect.  First, Kendo DOES NOT depend on angular even if you plan to use the Kendo UI angular directives so you can remove that dependency.  Second, the "jquery" you list isn't actually jquery.  I had to read the browserify-shim documents quite a few times, but that "jquery" you have is just a reference to the the npm library jquery, NOT the variable that jQuery will attach to the DOM (which is jQuery or $).  Also, if you want the kendo library globally available in your app, then you want to export or expose kendo.  So your final kendo entry should be:

    "kendo" : {
    "depends": [ "jquery:jQuery" ],
    "exports": "kendo"
    }

    Finally, I didn't see it in your package.json file, but you need to tell browserify about the shims you setup.  YOu do this by including a transformation in the package.json file:

    "browserify": {
    "transform": [
    "browserify-shim"
    ]
    },

    All in all, our package.json should look like this:
    "browser": {
    "angular" : "./node_modules/angular/angular.js",
    "kendo": "./kendo-ui/kendo.all.min.js"
    },
    "browserify-shim": {
    "angular" : {
    "exports" : "angular",
    "depends" : ["jquery:jQuery"]
    },
        "kendo": {
          "exports": "kendo",
          "depends": [
            "jquery:jQuery"
          ]
        },
    },
      "browserify": {
        "transform": [
          "browserify-shim"
        ]
      }

    See my follow on post where i make a few comments about Browserify and Kendo.










  12. Nathan
    Nathan avatar
    4 posts
    Member since:
    Nov 2014

    Posted 12 Dec 2014 in reply to Nathan Link to this post

    So this is more a comment than an issue or "fix".

    Browserify is really nice.  I also like using watchify or gulp-watch to do live-reloading of my pages during development.  However, bundling up all your js dependencies into one large js file makes watchify or gulp-watch almost useless since vendor libs (like jQuery, Kendo.UI, etc.) are so large that it takes a long time for Browserify to create the bundle and to re-push it to the web page.

    There are a few options I've researched to "improve" this process:
    1) If a vendor lib is standalone and/or NOT CommonJS-compliant, then it has no 'require' statements in it and there's no reason Browserify should parse it.  You can pass options to the noParse argument of Browserify to say, hey don't walk this Library for other 'require' paths.

    2) Use browserify to create TWO js bundles: one for all 3rd party/external libs that never change; one for your application's js code.  By doing so, your watchify or gulp watch task will only have to re-browserify a small set of application js code when that changes.  Since the 3rd party libs should never change, you'll only need to run browserify whenever you add or remove a 3rd party lib.  To do this, according to the Browserify documentation and handbook, you use the external and require options when you run Browserify.  Although I've read 3-4 articles/blogs on how to do this, I just can't get it to work.  I've submitted a possible "issue" here with the Browserify team: GitHub Issue

    It sounds like I'm not the only one struggling with this issue especially in newer releases of browserify.  Here's a list of articles that describe the process I was trying to get working:
    https://lincolnloop.com/blog/speedy-browserifying-multiple-bundles/
    http://9elements.com/io/index.php/external-bundles-with-browserify-and-gulp/
    http://benclinkinbeard.com/posts/external-bundles-for-faster-browserify-builds/
    https://github.com/thlorenz/browserify-shim/wiki/browserify-shim-recipes#bundling

    I just stumbled across this, which looks to be recent (4 months ago since Nov 2014) and may actually work.  I haven't tried it yet, but will give it a shot soon I hope: https://github.com/sogko/gulp-recipes/tree/master/browserify-separating-app-and-vendor-bundles

    3) Since I was unable to get #2 to work, I instead decided to use exposify which oddly enough is suggested to be used on the Angular NPM home page.  Exposify allows you to tell Browserify to "ignore" adding 3rd party vendor libraries/libs and that they will be available "globally".  You then load your 3rd party libs in the head of your HTML page (which would also allow you to use CDN and possibly use any cached versions of 3rd party libs your users may have already cached in their browser):
    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
     
        <title>TITLE GOES HERE</title>
     
        <link rel="stylesheet" href="./styles/app.css">
     
        <script src="./libs/jquery.js"></script>
        <script src="./libs/angular.js"></script>
        <script src="./libs/hammer.js"></script>
        <script src="./libs/kendo.all.min.js"></script>
        <script src="./libs/nsPopover.js"></script>
        <script src="./libs/jquery.steps.js"></script>
     
    </head>
    <body layout="column" layout-fill md-theme="bpt" ng-controller="appCtrl">
     
    <div class="test" flex layout="column" layout-align="center center" ui-view>
     
    </div>
     
    <script src="./app_bundle.js"></script>
     
    </body>
    </html>

    As you can see my index.html pulls in most of my large, 3rd party libs (where i can use CDN, etc) and then my app_bundle at the bottom of the page just loads my application-specific code + any small 3rd party libs.

    Here's my exposify config:
    exposify.config = {
      jquery: 'jQuery',
      angular: 'angular',
      hammer: 'hammerJS',
      kendo: 'kendo',
      nsPopover: 'nsPopover'
    };

    Ideally, I'd like to get the vendor + application bundles working in #2 but this #3 seems to work as well.

    4) If you purchase the Kendo UI pro version you have the option of choosing what specific UI components you want and Kendo's webpage will generate a custom JS lib file.  Highly recommended if you don't need all of Kendo UI in your web app since even minified the kendo.all.min.js file is quite large even if you do externalize it from your app js code via external bundle or exposify.

    If anyone has any experience, comments, or suggestions on this topic, I'm all ears.  Also, if anyone has indeed been able to bundle kendo UI into a vendor bundle using Browserify externals, please chime in!








Back to Top
Kendo UI is VS 2017 Ready