2016-08-17 10 views
1

Я пытаюсь использовать RequireJS для модуляции нашего JS в несколько больших JS-файлов, чтобы зависимости можно было загружать по требованию, но без загрузки большого одиночного JS-файла при загрузке страницы.Оптимизация RequireJS во множестве модулей

В качестве примера, с файлами JS как:

  • JS/main.js
  • JS/просмотр/category1/js1.js
  • JS/просмотров/category1/js2.js
  • JS/просмотров/category2/js1.js
  • JS/просмотров/category2/js2.js

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

Я пытаюсь создать конфигурацию для r.js для создания двух динамически загружаемых модулей (category1.js & category2.js), которые содержат весь код из соответствующих файлов js1.js и js2.js.

({ 
appDir: './', 
baseUrl: './js', 
dir: './dist', 
modules: [ 
    { 
     name: 'main', 
     exclude: [ 
      "category1", 
      "category2" 
     ] 
    }, 
    { 
     name: "category1", 
     include: [ 
      "views/category1/js1", 
      "views/category1/js2" 
     ], 
     create: true 
    }, 
    { 
     name: "category2", 
     include: [ 
      "views/category2/js1", 
      "views/category2/js2" 
     ], 
     create: true 
    } 
], 
fileExclusionRegExp: /^(r|build)\.js$/, 
writeBuildTxt: false, 
optimizeCss: 'standard', 
removeCombined: true, 
paths: { 
    jquery: 'lib/jquery', 
    underscore: 'lib/underscore', 
    backbone: 'lib/backbone/backbone' 
}, 
shim: { 
    underscore: { 
     exports: '_' 
    }, 
    backbone: { 
     deps: [ 
      'underscore', 
      'jquery' 
     ], 
     exports: 'Backbone' 
    } 
} 
}) 

Однако при загрузке скомпилированного выхода, браузер жалуется, что он не может найти вид/category1/СП1, просмотры/category1/js2 и так далее.

Я даже не уверен, что можно создать несколько высокоуровневых модулей из нескольких меньших JS-файлов в RequireJS. Имел ли кто-нибудь опыт с этим?

EDIT

main.js:

require.config({ 
    shim: { 
     underscore: { 
      exports: '_' 
     }, 
     backbone: { 
      deps: [ 
       'underscore', 
       'jquery' 
      ], 
      exports: 'Backbone' 
     } 
    }, 
    paths: { 
     jquery: 'lib/jquery', 
     underscore: 'lib/underscore', 
     backbone: 'lib/backbone/backbone' 
    } 
}); 

require([ 
    'views/app', 
    'router' 
], function(AppView, Router) { 
    new Router(); 
    Backbone.history.start(); 
}); 

index.html:

<!doctype html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <script data-main="js/main" src="js/lib/require/require.js"></script> 
</head> 
<body></body> 
</html> 

СП1, СП2 и т.д. файлы которые ссылаются из router.js.

ответ

2

Когда вы require(['A'], ...) или у вас есть define(['A'], ..., RequireJS проверяет свою конфигурацию, чтобы разрешить имя A, и строит URL, который он использует, чтобы загрузить модуль A. Он может попытаться загрузить что-то вроде:

http://localhost/js/A.js 

Если оптимизировать модули так, что A, B, C включены в пачке по имени category1, у вас есть следующие возможности:

  1. Расслоение Загружается category1, а затем выполняется запрос для A. Это нормально, потому что A был найден при загрузке category1.

  2. Пакет еще не загружен, но запрос сделан для A. Это проблема, потому что она разрешит A так же, как без оптимизации.Но у вас проблема, потому что если вы оптимизировали свои модули, то A больше не доступен за пределами category1 (потому что removeCombined - true).

Решение должно указать RequireJS в вашей конфигурации времени выполнения, что в комплект поставки входят модули, которые вы хотите загрузить. Для этого вы используете опцию bundles. Например:

bundles: { 
    category1: ['A', 'B', 'C'] 
} 

Это говорит RequireJS «когда вы хотите загрузить модуль A, загрузите category1 и вы найдете его там».

Обратите внимание, что вам не нужно перечислять каждый модуль в комплекте. Например, если у вас есть модуль X, и вы знаете, что единственные модули, которые захотят его загрузить, являются частью одного и того же пакета, тогда вам не нужно указывать его как модуль в bundles.