How can you load multiple JQuery plugins?

2019-06-01 07:26发布

问题:

How can you load multiple JQuery plugins that use the $ to access methods? My configuration file (config.js) is as follows:

var require = {
    paths: {
        "jquery": "lib/jquery",
        "jqueryui": "lib/jquery-ui",
        "semanticui": "lib/semantic",
    },
    shim: {
        "jqueryui": {
            exports: "$",
            deps:['jquery']
        },
        "semanticui": {
            exports: "$",
            deps: ['jquery']
        }
    }};

My application file (load.js) is defined as follows:

define(['jqueryui', 'semanticui'], function ($) {
    console.log($);
})

I found that the $ was undefined. However when I use the following code below:

define(['semanticui', 'jqueryui'], function ($) {
    console.log($);
})

$ is defined as the jQuery object.

Is it possible to use the $ to access jQuery and the methods defined by the plugins?

This is the index.html file I use:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Dashboard</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="./css/app.css">
    <script type="text/javascript" src="config.js"></script>
    <script data-main="load" src="lib/require.js" async></script>
</head>

<body>
    <!--NAVIGATION BAR-->
    <div class="ui fixed inverted menu">
        <div class="ui fluid container">
            <div class="header item" id="activateSidebar">AthenaViz<i class="terminal icon"></i></div>
        </div>
    </div>
    <!--END OF NAVIGATION BAR-->
    <!--SIDEBAR MENU-->
    <div class="ui left vertical  sidebar labeled icon menu">
        <a class="item">
        </a>
        <a class="item">
            <i class="fa fa-pie-chart"></i> Dashboard
        </a>
        <a class="item">
            <i class="fa fa-eye"></i> Visualize
        </a>
    </div>
    <!--END OF SIDEBAR MENU-->
    <div class="pusher">
<table class="ui striped table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Date Joined</th>
      <th>E-mail</th>
      <th>Called</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Lilki</td>
      <td>September 14, 2013</td>
      <td>jhlilk22@yahoo.com</td>
      <td>No</td>
    </tr>
    <tr>
      <td>Jamie Harington</td>
      <td>January 11, 2014</td>
      <td>jamieharingonton@yahoo.com</td>
      <td>Yes</td>
    </tr>
    <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>jilsewris22@yahoo.com</td>
      <td>Yes</td>
    </tr>
          <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>jilsewris22@yahoo.com</td>
      <td>Yes</td>
    </tr>
          <tr>
      <td>Jill Lewis</td>
      <td>May 11, 2014</td>
      <td>jilsewris22@yahoo.com</td>
      <td>Yes</td>
    </tr>
  </tbody>
</table>
    </div>
</body>

</html>

回答1:

You should not use a shim with jQuery UI, because it calls define by itself, and shim is only for modules that do not call define. If you look at the code here, you'll see near the start of the file:

(function( factory ) {
    if ( typeof define === "function" && define.amd ) {

        // AMD. Register as an anonymous module.
        define([ "jquery" ], factory );
    } else {

        // Browser globals
        factory( jQuery );
    }
}(function( $ ) {

And it looks like the factory function does not return anything, which explains why you got $ set to undefined.

Semantic UI does need a shim because it does not call define.

I suggest that instead of trying to grab $ from the plugins, you get it from jquery itself:

define(['jquery', 'jqueryui', 'semanticui'], function($) {
  console.log($);
});

The order may appear strange but it will work fine. You have to think about how jQuery plugins install themselves: they modify the jQuery object, which is $ here. So the code above will load jquery, then load jqueryui, which will modify jQuery to add itself as a plugin, and load semanticui, which will also modify jQuery to add itself as a plugin. (Actually, semanticui could load before jqueryui because one is not dependent on the other, but it does not change the end result.) So the $ that you get into your anonymous function will have the plugins installed on it.

I do what I'm suggesting above all the time, without any issue, but I use the CommonJS idiom:

define(function (require, exports, module) {
    var $ = require("jquery");
    require("bootstrap");
    require("jquery.bootstrap-growl");
});

bootstrap and jquery.bootstrap-growl install themselves as jQuery plugins, but I get my reference from jquery itself.

(The CommonJS idiom is not better. It's just what I use.)