cujojs / curl

curl.js is small, fast, extensible module loader that handles AMD, CommonJS Modules/1.1, CSS, HTML/text, and legacy scripts.
https://github.com/cujojs/curl/wiki
Other
1.89k stars 216 forks source link

How do I load a jquery plugin? #203

Closed dodozhang21 closed 10 years ago

dodozhang21 commented 10 years ago

Is there a way to load a jquery plugin with curl? If so, how would I accomplish that? Thanks in advance!

adrianmiu commented 10 years ago

You would need the js and css plugins

curl(['js!/path-to-jquery/jquery.js!order', 'js!/path-to-jqueryui/jquery.ui.js!order', 'css!/path-to-jqueryui/jquery.ui.css'], function() {
     // jquery ui is ready to be used here
});

Sorry for the shameless plug but if you want to use jQuery plugins you can use www.feaxures.com It uses curl.js for loading the files.

unscriptable commented 10 years ago

Thanks @adrianmiu! Feaxures is cool!

Another way:

  1. Create a custom jQuery UI bundle and css file at http://jqueryui.com/download.
  2. Copy the jquery-ui-1.xx.yy.custom.min.js file and the jquery-ui-1.xx.yy.custom.min.css files into your project (as well as jquery, of course).
  3. Map a path or package to jquery in your curl config and preload it.
curl.config({
    paths: { jquery: 'lib/jquery/jquery-1.9.3.min.js' },
    preloads: ['jquery']
});

Require the jqueryUI and css where you need it. If you would like 100% error/404 detection in IE, also include an exports suffix, like this:

define(['js!lib/jqueryui/jquery-ui-1.xx.yy.custom.min.js!exports=$.ui', 'css!lib/jqueryui/jquery-ui-1.xx.yy.custom.min.css'], function () {
    // do stuff with jquery ui here
});
adrianmiu commented 10 years ago

@unscriptable The last piece of code will actually define a module that depends on jQuery but you will need to load it afterwards to actually execute the code inside the "// do stuff with jquery ui here" function, correct?

unscriptable commented 10 years ago

Yes. That module defined by that last snippet will need to get loaded, either by being required by another module or by being curl()ed as a "top-level" or "main" module. :)

dodozhang21 commented 10 years ago

this is my first attempt of using curl so bear with me.

is js a plugin for curl? here's what I have. i'm pulling curl from the cdn:

<!DOCTYPE html>
<html>
  <head>
    <style>#container { position: relative }</style>
    <link rel="stylesheet" href="css/flexslider.css" type="text/css" media="screen" />
    <script type="text/javascript">
      curl = {
        paths: {
          'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min'
          ,'flexslider2': 'js!js/lib/jquery.flexslider'
        },
        preloads: ['jquery'],
        apiName: 'require'
      };
    </script>
    <script src="//cdn.jsdelivr.net/curl.js/0.7.5/curl/curl.js"></script>
    <script src="js/bootstrap.js"></script>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

My bootstrap.js

define.amd.jQuery = true

require([
  'jquery'
  ,'birthdayPlanner'
], function($, birthdayPlanner){

  $(document).ready(function(){
      birthdayPlanner.doMoreStuff();
  });
});

define('planner',
    ['flexslider2'],
function () {
    var planner = {
        doStuff:function(){
            $('#container').html('<ul class="slides"><li><img src="http://flexslider.woothemes.com/images/kitchen_adventurer_cheesecake_brownie.jpg"/></li><li><img src="http://flexslider.woothemes.com/images/kitchen_adventurer_lemon.jpg"/></li></ul>');
            $('#container').flexslider({
                animation: "slide"
            });
            return;
        }
    }

    return planner;
});

define('birthdayPlanner',
    ['planner'], 
function(planner) {

    var birthdayPlanner = {
        doMoreStuff: function() {
            planner.doStuff();

            console.log('hi from birthdayplanner');
        }
    }

    return birthdayPlanner;
});

I get error:

"NetworkError: 404 Not Found - http://localhost:1234/playingWithCurl/js!js/lib/jquery.flexslider.js"
unscriptable commented 10 years ago

Hey @dodozhang21,

Not bad for your first time! :) A couple of things:

  1. If you want to use curl off of the CDN and want to use plugins, try one of the pre-bundled versions of curl. This one has the js!, domready!, and css! plugins built in: //cdn.jsdelivr.net/curl.js/0.7.5/jquery/curl.js (If you don't use a pre-bundled version, the plugins must be fetched off your web server, so you need to map a path to them.)
  2. You shouldn't need define.amd.jQuery = true since curl already does that, but I guess it doesn't hurt.
  3. I see you mapped the global curl to require. I always warn against this. Reason: it's too easy to confuse the global require from the local require -- the one you can request from inside a module. These two require functions act a bit differently and can cause headaches when you get them confused. By keeping the global function curl, you won't get confused.
  4. You can simplify the "main module" a bit by using curl's domReady! plugin. (It's also a bit faster than jquery's.)
require([
  'jquery'
  ,'birthdayPlanner'
  ,'domReady!'
], function($, birthdayPlanner){
    // this won't execute until the dom is ready
    birthdayPlanner.doMoreStuff();
});

-- John

dodozhang21 commented 10 years ago

I changed my link to the jquery curl but I get the same error.

How do I fix #3?

If I were to load the plugin off my server, do I just download the whole plugin directory or can I just add to the curl.js?

dodozhang21 commented 10 years ago

I finally got js! to work but now it's saying:

ReferenceError: jQuery is not defined
[Break On This Error]   

})(jQuery);

if I do

define('flexslider2',['jquery'],function(jQuery) { // paste the plugin code here });

then depend on 'flexslider2', it works but i really don't want to having to paste the plugin code.

unscriptable commented 10 years ago

Ok. I see the problem...

It seems the current version of curl has a timing bug when using preloads and a separate script element to bootstrap. There are several ways to fix it, the easiest of which is to use a "main" config option rather than use a separate script element to load your bootstrap.

<!DOCTYPE html>
<html>
  <head>
    <style>#container { position: relative }</style>
    <link rel="stylesheet" href="css/flexslider.css" type="text/css" media="screen" />
    <script type="text/javascript">
      curl = {
        paths: {
          'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min'
          ,'flexslider2': 'js!js/lib/jquery.flexslider'
        },
        preloads: ['jquery'],
        // this will load your bootstrap file asap:
        main: 'js!js/bootstrap',
        apiName: 'require'
      };
    </script>
    <script src="//cdn.jsdelivr.net/curl.js/0.7.5/curl/curl.js"></script>
    <!--<script src="js/bootstrap.js"></script>-->
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>
unscriptable commented 10 years ago

It's cool that you're manually bundling some modules into your bootstrap.js file. However, be aware that AMD bundling tools like cram.js and r.js can work around many of the timing issues you might encounter when doing it manually.

dodozhang21 commented 10 years ago

Do you mind cloning my repo?

https://github.com/dodozhang21/curlSandbox

I'm still having issue. It's now saying:

"NetworkError: 404 Not Found - http://localhost:1234/curlSandbox/curl/plugin/js.js"

I don't understand why it's trying to load that plugin if it's already included in the curl.js?

unscriptable commented 10 years ago

Hey @dodozhang21,

When I cloned your repo and changed the configuration to this:

      curl = {
        paths: {
          'curl/plugin/text': 'js/lib/curl/plugin/text'
          ,'curl/plugin/_fetchText': 'js/lib/curl/plugin/_fetchText'
          ,'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'
          //,'flexslider2': 'js!js/lib/jquery.flexslider'
          ,'mustache': 'js/lib/mustache'
        }
        ,preloads: ['jquery']
        // this will load your bootstrap file asap:
        ,main: 'js!js/bootstrap.js'
      };

It all loaded fine -- except for the text! plugin which you didn't tell me about :) :) and isn't available on the CDN at the moment. :(

You can download curl and use it from your web server. Here's what I recommend to get started quickly:

  1. Install bower globally (first install node/npm, if you haven't already) by typing npm install bower -g
  2. clone the cujojs/seed project into a folder of your choice.
  3. type bower install flexslider2 from the root folder of the seed project.
  4. repeat bower install XXXXX for any other third-party resources you need.
  5. continue to customize the seed project to your needs.

When you have finished development and are ready to build a production version, from the root of the seed project:

  1. type bower install cram to install cram.js
  2. type cram index.html to build a bundled version.

I hope hat helps!

-- John

unscriptable commented 10 years ago

cujojs/seed: https://github.com/cujojs/seed

I just noticed that the index.html is missing instructions for cram.

When you are ready for cram, there are a few options. Here's the simplest one:

Change this line:

<script src="app/run.js"></script>

to this:

<script data-curl-run src="app/run.js"></script>

That tells cram where your bootstrap file is. (We call it a run.js file.)

-- John

dodozhang21 commented 10 years ago

Thank you for all of your tips John. I did look at seed but the reason I did not go with it is because we are currently using headjs and grunt for our projects. I just wanted a loader that will allow me to use AMD and I really like the text plugin for curl as well. That's why I didn't use the whole cujo suite.

Not sure if that's a good idea but we don't want to drop headjs and grunt at this point. So let me know if you think combing curl, headjs, grunt is a good idea or if I should look for something else?

Thanks

dodozhang21 commented 10 years ago

I assume I can build a custom version of curl that includes js, domReady & text using cram? If so, how do I do that?

unscriptable commented 10 years ago

It seems overly difficult to use headjs and curl.js (or any AMD loader) together in the same code base. It seems like there'd be lots of ordering and timing issues.

You can build your own curl.js! Take a peek at the bin/make-all.js file to see some examples.

-- John

unscriptable commented 10 years ago

Fwiw, grunt does not conflict in any way with AMD, curl.js, or cujoJS. We use grunt.

unscriptable commented 10 years ago

Hey @dodozhang21, closing this issue. Please reopen it if you have more questions or issues. Thanks! -- John