RequireJS не работает в многостраничном проекте с библиотеками, размещенными на CDN (jQuery)
Я использую RequireJS для многостраничного проекта с структурой папок Javascript, которая выглядит как это (как вы делаете эти причудливые деревья снова в Markdown?):
common.js
lib/
-- jquery-1.9.1.min.js
-- modernizr-2.6.2.min.js
-- underscore-amd.min.js
page/
-- index.js
-- start.js
-- checkout.js
В любом случае, common.js
- это мой основной файл script, где я устанавливаю параметры конфигурации. Вот что это выглядит:
файл common.js
// Configure RequireJS
requirejs.config({
baseUrl: "assets/js/lib",
paths: {
page: '../page',
jquery: [
'//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min',
//If the CDN location fails, load from this location
'jquery-1.9.1.min'
],
modernizr: [
'//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min',
//If the CDN location fails, load from this location
'modernizr-2.6.2.min'
],
underscore: [
'underscore-amd.min'
]
}
});
Все вызовы страниц работают так, как ожидалось (при загрузке места CDN), но я не могу опустить голову над частью минимизации. Оптимизатор r.js
просто отказывается сотрудничать, бросая Error: paths fallback not supported in optimizer. Please provide a build config path override for underscore
, хотя в Underscore нет указанного CDN.
файл build.js
{
appDir: '../www',
baseUrl: 'js/lib',
dir: '../www-built',
mainConfigFile: '../www/assets/js/common.js',
modules: [
//First set up the common build layer.
{
//module names are relative to baseUrl
name: '../common',
include: ['jquery',
'modernizr',
'underscore'
]
},
// Now the page scripts
{
//module names are relative to baseUrl/paths config
name: '../page-index',
include: ['page/index'],
exclude: ['../common']
},
],
paths: {
jquery: "empty",
modernizr: "empty"
},
optimize: "uglify2",
removeCombined: true
}
Пожалуйста, помогите мне разобраться, как создать этот проект для создания common.js
script вместе с отдельными сценариями страницы.
(Примечание. Я основал структуру моего файла build.js
на в этом примере
Обновлено!
Я обновил вопрос, включив правильный синтаксис для empty:
(спасибо Travis!), и теперь сборка работает без ошибок. Однако мои JS файлы не объединены или не очищены. Файлы CSS находятся в точках импорта, поэтому что-то происходит. Заполните build.js
файл ниже (простите меня, но она высокая):
{
appDir: '../www',
baseUrl: 'assets/js', // relative to appDir
dir: '../www-built',
mainConfigFile: '../www/assets/js/common.js',
modules: [
//First set up the common build layer.
{
//module names are relative to baseUrl
name: 'common',
//List common dependencies here. Only need to list
//top level dependencies, "include" will find
//nested dependencies.
include: ['jquery',
'modernizr',
'underscore',
'bootstrap'
]
},
//Now set up a build layer for each page, but exclude
//the common one. "exclude" will exclude nested
//the nested, built dependencies from "common". Any
//"exclude" that includes built modules should be
//listed before the build layer that wants to exclude it.
//"include" the appropriate "app/main*" module since by default
//it will not get added to the build since it is loaded by a nested
//require in the page*.js files.
{
//module names are relative to baseUrl/paths config
name: 'pages/home',
include: ['pages/home'],
exclude: ['common']
},
{
//module names are relative to baseUrl/paths config
name: 'pages/start',
include: ['pages/start'],
exclude: ['common']
},
{
//module names are relative to baseUrl/paths config
name: 'pages/checkout',
include: ['pages/checkout'],
exclude: ['common']
},
],
paths: {
jquery: "empty:",
modernizr: "empty:"
// underscore: "empty:"
},
optimize: "uglify2",
optimizeCss: "standard",
removeCombined: true,
preserveLicenseComments: false
}
Окончательное обновление (Yaay! It working)
Благодаря Тревису ниже, все отлично работает! (файлы становятся миниатюрами и конкатенированы). Поскольку его решение размещено на Dropbox и может быть потеряно в будущем (кто знает амирит?), Я просто подытожу исправления, которые он сделал:
1. Не смешивайте вызовы define
и require
в одном файле.
У меня было несколько файлов, где я их смешивал так:
страница /start.js
define(['jquery','underscore'],function($,_) {
...
});
require(['jquery','page/start'], function($, Y) { // BAD!
...
});
и исправление должно было сделать это:
страница /start.js
require(['jquery','app/start_helper'], function($, Y) {
...
});
приложение /start _helper.js
define(['jquery','underscore'],function($,_) {
...
});
2. Это "empty:"
не "empty"
Это сложный вопрос, хотя упоминания о них требуют документы RequireJS.
3. Поскольку
в каком списке есть только 2 балла?
Awesomeelicious - теперь он работает как шарм:)
Ответы
Ответ 1
Похоже, что requireJs думает, что вы пытаетесь предоставить резервную копию пути для подчеркивания, поскольку вы указываете его значение пути как массив. Попробуйте просто сделать это как строку вместо.
paths: {
underscore: 'underscore-amd.min'
}
Также обратите внимание, что правильный символ для пустых путей - empty:
(с ':') не empty
.
Наконец, в качестве несвязанной стороны вы всегда можете посмотреть lodash, которая является IMHO более настраиваемой, кросс-браузерной, более быстрой заменой подчеркивания с идентичным API и он размещен на cdnjs и совместим с AMD
UPDATE
Следуя за разговором в комментариях, здесь моя обновленная версия вашего проекта: https://dl.dropboxusercontent.com/u/21823728/so_rjs.tar.gz
Как уже упоминалось в комментариях, ваша проблема, похоже, заключалась в том, что вы были define
встроенными модулями в том же файле, в котором вы нуждались в этих модулях, и что я считаю, что r.js полагает, что у этих модулей не было основная точка входа. Соглашение состоит в том, чтобы отделить определения модулей от файлов, требующих этих модулей.
Обратите внимание на папку app
в разделе assets/js
, где теперь хранятся каждый модуль, который раньше был define
d в ваших модулях страниц. Теперь модули страниц теперь require
включены в эти модули. Когда я снова запустил r.js
(используя uglify2 в качестве оптимизатора), все, казалось, работало так, как ожидалось.
Кроме того, я удалил некоторую избыточность из файла build.js(вам нужно указать baseUrl в mainConfigFile, если тот, который вы используете для вашей конфигурации сборки). Наконец, вы можете захотеть изучить конфигурацию shim, если вы хотите присоединить jQuery и Bootstrap глобально к каждой странице. В противном случае вам следует просто указать их как зависимости, когда они вам понадобятся.
Наконец, в качестве одного из последних советов вам может потребоваться сократить количество require
в каждом файле. На большинстве этих страниц вы можете обернуть все в один вызов, а затем просто разделить другую логику на функции, чтобы сохранить некоторое пространство в очереди событий, а также некоторые циклы, чтобы избыточно вызвать функцию require
.