Требуется оптимизация JS в несколько модулей

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

Например, с файлами JS как:

  • js/main.js
  • js/представления/категория1/js1.js
  • js/представления/категория1/js2.js
  • js/представления/категория2/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'
    }
}
})

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

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

ИЗМЕНИТЬ

основной.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();
});

индекс.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>

На файлы JS1, JS2 и т. д. ссылаются из router.js.


person BB1    schedule 17.08.2016    source источник


Ответы (1)


Когда вы делаете 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.

person Louis    schedule 17.08.2016