Требовать, чтобы JS игнорировал мою конфигурацию - программирование
Подтвердить что ты не робот

Требовать, чтобы JS игнорировал мою конфигурацию

У меня довольно простая структура каталогов для скриптов:

/js/        <-- located in site root
    libs/
        jquery-1.10.1.min.js
        knockout-2.2.1.js
        knockout.mapping.js
    models/
        model-one.js
        model-two.js
        ...
    require.js
    config.js

Поскольку механизм сайта использует чистые URL-адреса, я использую абсолютные пути в <script>:

<script type="text/javascript" data-main="/js/config.js" src="/js/require.js"></script>

RequireJS config:

requirejs.config({

    baseUrl: "/js/libs",

    paths: {
        "jquery":       "jquery-1.10.1.min",
        "knockout":     "knockout-2.2.1",
        "komapping":    "knockout.mapping"
    }

});

Где-то в HTML:

require(["jquery", "knockout", "komapping"], function($, ko, mapping){
    // ...
});

Таким образом, проблема заключается в том, что RequireJS полностью игнорирует baseUrl и paths, определенные в файле конфигурации. Я получаю ошибку 404 для каждого модуля, требуемого в приведенном ниже коде. Я вижу в консоли браузера, что RequireJS пытается загрузить эти модули из /js/ без каких-либо переводов путей:

404: http://localhost/js/jquery.js
404: http://localhost/js/knockout.js
404: http://localhost/js/komapping.js

Однако после загрузки страницы и появления ошибок я набираю консоль и...

> require.toUrl("jquery")
  "/js/libs/jquery-1.10.1.min"

Почему так? Как решить эту проблему?

Это мой первый опыт использования RequireJS, поэтому я чувствую, что пропустил что-то очень простое и очевидное. Помогите, пожалуйста.

Обновление

Только что открыл этот вопрос: Require.js игнорирует baseUrl

Это определенно мой случай. Я вижу на панели "Сеть", что config.js не полностью загружен до того, как require(...) запускает собственную загрузку зависимостей.

Но я не хочу размещать свой require(...) в config, потому что он очень специфичен для вызываемой страницы. Я никогда не замечал такой проблемы с асинхронностью в любом примере, который видел прежде. Как авторы этих примеров поддерживают их работу?

4b9b3361

Ответ 1

решаемые.

Проблема заключалась в том, что конфигурационный файл, определенный в атрибуте data-main, загружается асинхронно точно так же, как и другие зависимости. Поэтому мой config.js случайно не был полностью загружен и выполнен до вызова require.

Решение описано в официальном RequireJS API: http://requirejs.org/docs/api.html#config

... Кроме того, вы можете определить объект конфигурации как требуемую глобальную переменную перед загрузкой require.js и автоматически использовать значения.

Итак, я только что изменил свой config.js, чтобы определить глобальный хеш require с правильной конфигурацией:

var require = {
    baseUrl: "/js/libs",
    paths: {
        "jquery":       "jquery-1.10.1.min",
        "knockout":     "knockout-2.2.1",
        "komapping":    "knockout.mapping"
    }
};

и включил его только до require.js:

<script type="text/javascript" src="/js/config.js"></script>
<script type="text/javascript" src="/js/require.js"></script>

Этот подход позволяет управлять порядком выполнения script, поэтому config.js всегда будет загружаться перед следующими вызовами require.

Теперь все работает отлично.

Ответ 2

Исправлена ​​проблема.

Моя конфигурация загружалась асинхронно, поэтому пути конфигурации не были установлены до вызова оператора require.

В соответствии с документами RequireJS Ссылка здесь, я добавил вызов script в мою конфигурацию перед вызовом require.js. И удалил основной атрибут data.

var require = {
    baseUrl: '/js',
    paths: {
        'jquery':      'vendor/jquery/jquery-2.0.3.min',
        'picker':      'vendor/pickadate/picker.min',
        'pickadate':   'vendor/pickadate/picker.date.min'
    },
    shim: {
        'jquery': {
            exports: '$'
        },
        'picker':    ['jquery'],
        'pickadate': {
            deps:    ['jquery', 'picker'],
            exports: 'DatePicker'
        }
    }
}

Теперь все работает