Как я могу использовать потребности и jQuery вместе?

StackOverflow https://stackoverflow.com/questions/4535926

  •  13-10-2019
  •  | 
  •  

Вопрос

Я хотел бы использовать requirejs и использую jQuery. Я не хочу использовать комбинированную версию requirejs и jQuery, так как я не использую последнюю версию jQuery. Как лучше всего работать с потребностями?

Это было полезно?

Решение

Это тоже мой вопрос! Я также должен использовать более старый jQuery, но также более «традиционные» библиотеки JavaScript. Какова лучшая техника для этого? (Я могу отредактировать ваш вопрос, чтобы сделать его более широким, если вы не возражаете.) Вот что я узнал.

АВТОР ТРЕБОВАНИЯ ДЖЕЙМС БЕРК Преимущества комбинированного файла requirejs + jQuery. Анкет Вы получаете две вещи.

  1. Модуль, jquery, доступен, и это объект jQuery. Это безопасно:

    // My module depends on jQuery but what if $ was overwritten?
    define(["jquery"], function($) {
      // $ is guaranteed to be jQuery now */
    })
    
  2. jQuery уже загружен до любого require() или же define() вещи. Все модули гарантированы, что jQuery готов. Вам даже не нужно require/order.js Плагин с тех пор, как jQuery был в основном жестко, чтобы загрузить первым.

Для меня #2 не очень полезно. У большинства реальных приложений есть много .js файлы это должен Загрузите в правильном порядке - SAD, но правда. Как только вам понадобится Sammy или Underscore.js, комбинированный файл requirejs+jQuery не помогает.

Мое решение состоит в том, чтобы написать простые обертки, которые загружают мои традиционные сценарии, используя плагин «заказ».

Пример

Предположим, что у моего приложения есть эти компоненты (по зависимости).

  • Мое приложение, GreatApp
    • GreatApp зависит от пользовательского jQuery (Старая версия, которую я должен использовать)
    • GreatApp зависит от my_sammy (Sammyjs плюс все его плагины, которые я должен использовать). Эти должен быть в порядке
      1. my_sammy зависит от jQuery (Sammyjs - плагин jquery)
      2. my_sammy зависит от Sammy.js
      3. my_sammy зависит от Sammy.json.js
      4. my_sammy зависит от Sammy.storage.js
      5. my_sammy зависит от sammy.mustache.js

На мой взгляд, все выше этого заканчивается .js это «традиционный» сценарий. Все без .js это плагин requirejs. Ключ: вещи высокого уровня (GreatApp, My_sammy)-это модули, а на более глубоких уровнях он возвращается к традиционным .js файлы

Загрузка

Все начинается с того, что буттер рассказывает, как это нужно начать.

<html>
  <head>
    <script data-main="js/boot.js" src="js/require.js"></script>
  </head>
</html>

В js/boot.js Я ставлю только конфигурацию и как запустить приложение.

require( // The "paths" maps module names to actual places to fetch the file.
         // I made modules with simple names (jquery, sammy) that will do the hard work.
         { paths: { jquery: "require_jquery"
                  , sammy : "require_sammy"
                  }
         }

         // Next is the root module to run, which depends on everything else.
       , [ "greatapp" ]

         // Finally, start my app in whatever way it uses.
       , function(greatapp) { greatapp.start(); }
       );

Основное приложение

В greatapp.js У меня нормальный модуль.

define(["jquery", "sammy"], function($, Sammy) {
  // At this point, jQuery and SammyJS are loaded successfully.
  // By depending on "jquery", the "require_jquery.js" file will run; same for sammy.
  // Those require_* files also pass jQuery and Sammy to here, so no more globals!

  var start = function() {
    $(document).ready(function() {
      $("body").html("Hello world!");
    })
  }

  return {"start":start};
}

Требуемые обертки модуля вокруг традиционных файлов

require_jquery.js:

define(["/custom/path/to/my/jquery.js?1.4.2"], function() {
  // Raw jQuery does not return anything, so return it explicitly here.
  return jQuery;
})

require_sammy.js:

// These must be in order, so use the "order!" plugin.
define([ "order!jquery"
       , "order!/path/to/custom/sammy/sammy-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.json-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.storage-0.6.2-min.js"
       , "order!/path/to/custom/sammy/plugins/sammy.mustache-0.6.2-min.js"
       ]

       , function($) {
           // Raw sammy does not return anything, so return it explicitly here.
           return $.sammy;
         }
      );

Другие советы

Этот вопрос сейчас не менее двух лет, но я заметил, что это проблема с requirejs 2.0 (require-jquery.js использует jQuery 1.8.0, но последняя версия-1.8.2).

Если вы увидите этот вопрос, обратите внимание, что require-jquery.js теперь просто требуется.js и jquery.js, пюре вместе. Вы можете просто отредактировать read-jquery.js и заменить детали jQuery более новой версией.

Обновление (30 мая 2013 г.): Теперь, когда у требований есть пути и пробранные пути, есть новый способ импортировать плагины jquery и jquery, а старый метод больше не нужен, ни рекомендуемые. Анкет Вот сокращенная версия текущего метода:

requirejs.config({
    "paths": {
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min"
    }
});

define(["jquery"], function($) {
    $(function() {
    });
});

Видеть http://requirejs.org/docs/jquery.html для получения дополнительной информации.

Я обнаружил, что лучший подход - сохранить jQuery за пределами моей сборки.

Просто включите jQuery.min.js в свой HTML. Затем сделайте файл jquery.js с чем -то подобным ...

define([], function() {
    return window.$;
});

Обнаружил, что Anwer Jasonsmith чрезвычайно полезно, вероятно, больше, чем документация «Восстания».

Тем не менее, есть способ оптимизировать его, чтобы избежать отдельных запросов AJAX для (крошечных) модулей определения декорации («retemb_jquery» «require_sammy»). Я подозреваю, что R.JS сделает это на стадии оптимизации, но вы можете сделать это заранее, чтобы не сражаться с путем, система Baseuri.

index.html:

<html>
  <head>
    <script data-main="js/loader.js" src="js/require.js"></script>
  </head>
</html>

Loader.js:

// We are going to define( dependencies by hand, inline.
// There is one problem with that through (inferred from testing):
// Dependencies are starting to load (and execute) at the point of declaring the inline
// define, not at the point of require(
// So you may want to nest the inline-defines inside require( 
// this is, in a way, short replacement for Order plug in, but allows you to use
// hand-rolled defines, which the Order plug in, apparently does not allow.

var jQueryAndShims = ['jquery']

if(window.JSON == null){
    jQueryAndShims.push('json2')
    define(
        'json2'
        , ['js/libs/json2.min.js']
        , function() {
            return window.JSON
        }
    )
}
// will start loading the second we define it.
define(
    'jquery'
    , ['js/libs/jquery_custom.min.js']
    , function() {
        // we just pick up global jQuery here. 
        // If you want more than one version of jQuery in dom, read a more complicated solution discussed in
        // "Registering jQuery As An Async-compatible Module" chapter of
        // http://addyosmani.com/writing-modular-js/
        return window.jQuery 
    }
)

// all inline defines for resources that don't rely on other resources can go here.

// First level require(
// regardless of depends nesting in 'myapp' they will all start downloading 
// at the point of define( and exec whenever they want, 
// async in many browsers. Actually requiring it before the nested require makes
// sure jquery had *executed and added jQuery to window object* before
// all resolved depends (jquery plugins) start firing.
require(jQueryAndShims, function($) {

    // will start loading the second we define it.        
    define(
        'sammy_and_friends'
        , ['jquery','js/libs/jquery_pluginone.min.js','js/libs/jquery_plugintwo.min.js','js/libs/sammy.min.js']
        , function($) {
            // note, all plugins are unaltered, as they are shipped by developers.
            // in other words, they don't have define(.. inside.
            // since they augment global $ (window.jQuery) anyway, and 'jquery' define above picks it up
            // , we just keep on returning it.
            // Sammy is attached to $ as $.sammy, so returning just Sammy makes little sense
            return $
        }
    )

    // second level require - insures that Sammy (and other jQuery plugins) - 'sammy_and_friends' - is
    // loaded before we load Sammy plugins. I normally i would inline all sammy plugins i need 
    // (none, since i use none of them preferring jQuery's direct templating API
    // and no other Sammy plug in is really of value. )  right into sammy.js file. 
    // But if you want to keep them separate:
    require(['sammy_and_friends'], function() {

        // will start loading the second we define it.
        define(
            'sammy_extended'
            , ['sammy_and_friends','js/libs/sammy_pluginone.min.js','js/libs/sammy_plugintwo.min.js']
            , function($) {
                // as defined above, 'sammy_and_friends' actually returns (globall) jQuery obj to which
                // Sammy is attached.  So we continue to return $
                return $
            }
        )
        // will start loading the second we define it.
        define(
            'myapp'
            , ['sammy_extended', 'js/myapplication_v20111231.js'] 
            , function($, myapp_instantiator) {
                // note, myapplication may, but does not have to contain RequireJS-compatible define
                // that returns something. However, if it contains something like 
                // "$(document).ready(function() { ... " already it MAY fire before 
                // it's depends - 'sammy_extended' is fully loaded.
                // Insdead i recommend that myapplication.js returns a generator 
                // (app-object-generating function pointer)
                // that takes jQuery (with all loaded , applied plugins) 
                // The expectation is that before the below return is executed, 
                // all depends are loaded (in order of depends tree)
                // You would init your app here like so:
                return myapp_instantiator($)
                // then "Run" the instance in require( as shown below
            }
        )

        // Third level require - the one that actually starts our application and relies on
        // dependency pyramid stat starts with jQuery + Shims, followed by jQuery plugins, Sammy, 
        // followed by Sammy's plugins all coming in under 'sammy_extended'
        require(['jquery', 'myapp'], function($, myappinstance) {
            $(document).ready(function() {myappinstance.Run()})
        })
    }) // end of Second-level require
}) // end of First-level require

Наконец, myApplication.js:

// this define is a double-wrap.
// it returns application object instantiator that takes in jQuery (when it's available) and , then, that
// instance can be "ran" by pulling .Run() method on it.
define(function() {
    // this function does only two things:
    // 1. defines our application class 
    // 2. inits the class and returns it.
    return function($) {
        // 1. defining the class
        var MyAppClass = function($) {
            var me = this
            this._sammy_application = $.sammy(function() {
                this.raise_errors = true
                this.debug = true
                this.run_interval_every = 300
                this.template_engine = null
                this.element_selector = 'body'
                // ..
            })
            this._sammy_application.route(...) // define your routes ets...
            this.MyAppMethodA = function(blah){log(blah)}  // extend your app with methods if you want
            // ...
             // this one is the one we will .Run from require( in loader.js
            this.Run = function() {
                me._sammy_application.run('#/')
            }
        }
        // 2. returning class's instance
        return new MyAppClass($) // notice that this is INITED app, but not started (by .Run) 
        // .Run will be pulled by calling code when appropriate
    }
})

Эта структура (свободно заменяет (дубликаты?) Плагин заказа требуется, но) позволяет вам обрезать количество файлов, необходимых для AJAX, добавляя больше элемента управления в определение зависит и зависит от дерева.

Существует также большой бонус к загрузке jQuery отдельно (который обычно составляет 100 тыс.) - вы можете управлять кэшированием на сервере или кэш -jQuery в LocalStorage браузера. Взгляните на проект AMD-Cache здесь https://github.com/jensarps/amd-cache Затем измените определение (операторы, чтобы включить «Кэш!»: И это будет (навсегда :)) застрял в браузере пользователя.

define(
    'jquery'
    , ['cache!js/libs/jquery_old.min.js']
    , function() {
        // we just pick up global jQuery here. 
        // If you want more than one version of jQuery in dom, read a more complicated solution discussed in
        // "Registering jQuery As An Async-compatible Module" chapter of
        // http://addyosmani.com/writing-modular-js/
        return window.jQuery 
    }
)

Примечание о jQuery 1.7.x+ он больше не прикрепляется к объекту окна, поэтому вышеуказанное не будет работать с немодифицированным файлом jquery 1.7.x+. Там вы должны настроить свой jQuery **. JS, чтобы включить это до закрытия "}) (window);":

;window.jQuery=window.$=jQuery

Если у вас есть ошибки «jquery undefined» в консоли, это версия jquery, которую вы используете, не прикрепляется к окну.

Лицензия кода: общественный домен.

Раскрытие информации: JavaScript выше пахнет «псевдокодом», так как это перефразирование (ручное разрез) гораздо более подробного производственного кода. Код, как представлено выше, не гарантированно будет работать и не был проверен на работу, как представлено. Аудит, проверьте это. Полуиколоны нарочно опущены, так как они не требуются в соответствии с спецификацией JS, а код выглядит лучше без них.

В дополнение к ответу JHS, см. Более поздние инструкции по Страница require-jquery github из файла readme.md. Он охватывает как самый простой подход использования комбинированного файла jquery/require.js, так и как использовать отдельный jquery.js.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top