grunt requirejs игнорирует пути из моего mainConfigFile

Введение в проект

Мой проект представляет собой одностраничную витрину. В проекте несколько модулей, и каждый модуль содержит набор файлов controller.js, view.js и model.js, а также файл template.html. И использует requirejs для управления зависимостями.

Постановка задачи

Я хочу использовать mainConfigFile для предоставления путей к эталонным модулям в grunt-requirejs. Часть файла require.config моего mainConfigFile хранится в отдельном файле (base.dependency.config), а require.config.paths объединяются воедино с помощью символа подчеркивания во время выполнения.

base.dependency.config

config = {
    baseDependencyConfig: {
        paths: { ... }
        shim: { ... }
    }
}

main.js

var dependencies = config.baseDependencyConfig;
var basePaths = config.baseDependencyConfig.paths;
var extensionPaths = {
    // extra sets of paths
};

// combine base paths and extension paths at runtime using underscore
var dependencyPaths = _.extend(basePaths, extensionPaths);

dependencies.paths = dependencyPaths;
require.config(dependencies);

// application startup
require(['app', 'eventbus']) {
    // code
}

Ошибка

Однако grunt requirejs игнорирует mainConfigFile, grunt requirejs пытается найти «app.js» под корнем, хотя на самом деле «приложение» определено в путях require.config как

'app': 'modules/base/app/base.app.controller'

мой gruntFile:

module.exports = function (grunt) {
    grunt.initConfig({
        // ... other plugin config
        requirejs: {
            options: {
                baseUrl: 'public',
                // the paths for the named modules such as 'app' are defined 
                // in main.js under require.config paths
                name: 'main',
                include: [
                    'app',
                    'cart',
                    'category'
        ],
        out: 'public/build/app-optimized.js',
        mainConfigFile: 'public/main.js',
        findNestedDependencies: true,
        optimizeCss: 'none',
        cssImportIgnore: 'style/style.css, style/mocha.css',
            }
        }
    })
}

моя файловая структура

public
    |--modules/
    |       |--base/
    |       |       |--cart
    |       |       |--category
    |       |               |--category.controller.js
    |       |               |--category.view.js
    |       |               |--category.model.js
    |       |               └-category.template.html
    |       |
    |       └--extension/
    |
    |--style/
    |--image/
    |--main.js <-- main config file
    |--other .js files
  • mainConfigFile, main.js находится в корневом каталоге вместе с несколькими другими js-файлами запуска приложений.
  • основная масса файлов приложения находится в папке с модулями
  • каждая папка модуля содержит свой контроллер, js-файл представления и модели, а также файл template.html

Редактировать

gruntFile работал раньше с другой настройкой mainConfigFile (main.js):

require.config({
    paths: {...}
    shim: {...}
})

// application startup
require(['app', 'eventbus']) {
    // code
}

person Anna Morning    schedule 16.10.2013    source источник
comment
Что произойдет, если вы добавите косую черту к базовому URL-адресу, например baseUrl: '/public'? Также, где находится requirejs?   -  person Dropzilla    schedule 17.10.2013
comment
requirejs находится внутри папки public/scripts/lib. И /public не работает, потому что, честно говоря, public не является корневой папкой, в которой я запускаю grunt. Public — единственная корневая папка для приложения. Есть и другие компоненты проекта, например. stylesrc (без css), модульные тесты, модули узлов и т. д., живущие на одном уровне с общественностью.   -  person Anna Morning    schedule 17.10.2013
comment
Возможно ли, что вы не проходите назад достаточно далеко, как ../../public?   -  person Dropzilla    schedule 17.10.2013
comment
Привет, Dropzilla, спасибо за ответ на мой вопрос. Я не считаю, что найти public или requirejs - это проблема. Точная настройка с тем же gruntFile и файловой структурой работала, когда все require.config.paths были определены непосредственно внутри main.js. См. раздел изменить сообщения выше.   -  person Anna Morning    schedule 17.10.2013
comment
@user2480414 user2480414, у вас уже все получилось? У меня аналогичный макет проекта (хотя и немного более простая реализация конфигурации RequireJS), и я сталкиваюсь с той же ошибкой: r.js/RequireJs не учитывает конфигурацию моего пути, пытаясь загрузить jquery.js из baseUrl вместо настроенного относительного пути ../libs /jquery-N.NN.js (с суффиксом версии).   -  person try-catch-finally    schedule 22.04.2014


Ответы (1)


r.js использует Esprima в качестве парсера Javascript для извлечения объекта конфигурации из указанного mainConfigFile . Он ищет только определенные подписи в коде.

смотреть на

  • hasRequire(): определить, что узел AST является конфигурацией вызов кандидата
  • findConfig(): вызывает указанное выше решение о том, как извлечь конфиг

Я создал патч, сообщающий о распознавании

requirejs.config(_VariableToExport = { ... });

Это ограничено, и подход парсера Javascript очень усложняет создание r.js, способного извлекать конфигурации, созданные функциями (например, в вашем коде) или около того. Этот патч еще не отправлен в проект. Я пока борюсь с бюрократией.

Я думаю, что пока единственным рабочим решением является

  • не использовать mainConfigFile
  • экспорт конфигурации как модуль NodeJS
  • требуется main.js/config.js в Node (Grunt)
  • передача объекта в качестве значения атрибуту или методу конфигурации

См. мой комментарий к этой проблеме для наброска.

Этот подход проверен в другом, более старом проекте, над которым я работаю.

Относится к r.js 2.1.11.

person try-catch-finally    schedule 27.04.2014
comment
Содержит патч. Дайте мне знать, если это не сработает. - person try-catch-finally; 27.04.2014