r.js не может разрешить зависимости, упомянутые в shim
Я недавно присоединился к проекту, который построен с использованием Backbonejs (использует Marionette для визуализации вида) + nodejs. Они также используют requirejs для загрузки файлов backbonejs. Хотел бы добавить на этом этапе, что я никогда раньше не работал с backbonejs или requirejs и, следовательно, я борюсь с проблемой, которую я опишу позже.
Некоторый код, который поможет объяснить проблему, с которой я столкнулся (весь этот код уже был написан предыдущими разработчиками)
Структура папки:
/public
/js
/collection (consists all Backbone.js collections files)
/lib
/bower_components
/backone
/marionette
/etc
/models (consists all Backbone.js models files)
/views (consists all Backbone.js view files)
/main.js
/main.build.js
/app.js
/controller.js
/router.js
Код из файлов, которые, я думаю, относятся к проблеме:
main.js
requirejs.config({
paths: {
'async': 'lib/bower_components/requirejs-plugins/src/async',
'jquery': 'lib/bower_components/jquery/dist/jquery.min',
'underscore': 'lib/bower_components/underscore/underscore-min',
'lodash': 'lib/bower_components/lodash/dist/lodash.min',
'backbone': 'lib/bower_components/backbone/backbone',
'marionette': 'lib/bower_components/marionette/lib/backbone.marionette.min',
'markercluster':'lib/markercluster',
'jquerymobile': 'lib/jquery.mobile-1.4.0.min',
'hogan': 'lib/template-2.0.0.min',
'templates': '/templates',
'real': 'lib/mainjs',
'touch': 'lib/jquery.touchSwipe.min',
'mouse': 'lib/jquery.mousewheel',
'moment': 'lib/moment-2.5.1.min',
'humanize': 'lib/bower_components/humanize-plus/public/dist/humanize.min',
'validator': 'lib/bower_components/validator-js/validator.min',
'real': 'lib/mainfile'
},
shim: {
backbone: {
deps: ["underscore"]
},
marionette: {
deps: ["backbone"]
},
templates: {
deps: ["hogan", "jquery"]
},
real: {
deps: ["jquery", "jquerymobile", "touch", "mouse"]
},
markercluster: {
exports: "MarkerClusterer"
},
humanize: {
exports: "humanize"
}
},
waitSeconds: 0
});
define('gmaps', ['async!http://maps.google.com/maps/api/js?v=3&key=AIzaSyBiV8f88yLWJ_IMSdP1fVNO1-gt3eLVSgg&sensor=true&callback=gMapsCallback'], function(){
// define('gmaps', ['http://maps.google.com/maps/api/js?v=3&sensor=false'], function(){
return window.google.maps;
});
require(['app', 'templates', 'real'], function(app) {
app.start({
version: "0.9.9"
});
});
main.build.js
({
baseUrl: ".",
name: "main",
wrapShim: true,
out: "main-built.js"
})
app.js
define(['underscore', 'controller', 'router', 'models/Cache', 'views/RootView'], function(_, Controller, Router, Cache, RootView) {
var Application = Marionette.Application.extend({
propertyListPageSize: 3,
initialize: function() {
_.templateSettings = { interpolate : /\{\{(.+?)\}\}/g };
},
onStart: function(options){
new RootView();
this.controller = new Controller();
this.router = new Router({controller: this.controller});
this.cache = new Cache();
this.context = {};
//this.evHistory = [];//@todo remove once BB/marionette navigation is in place
if(Backbone.history) Backbone.history.start({ pushState: false });
if(Backbone.history.fragment === "") this.navigate('home');
},
navigate: function(fragment, trigger, replace){
this.router.navigate(fragment, {trigger:trigger, replace:replace});
},
back: function() {
window.history.back();
}
});
app = new Application();
return app;
});
rootView.js
define(['marionette', 'views/HomeView', 'views/HeaderView', 'views/FooterView', 'views/MenuView', 'views/VideoView', 'views/LocationSearchView', 'views/LoginView', 'views/FindView', 'views/ServicesView', 'views/ValueView', 'views/PropertyListView', 'views/SideBySideView', 'views/ConfirmRegistrationView', 'views/ForgotPasswordView', 'views/CreateAccountView', 'views/UserHomeView', 'views/MyBrokerView', 'views/GiveFeedbackView', 'views/SeeFeedbackView', 'views/ViewingScheduleView', 'views/MyViewingsSummaryView', 'views/MyAccountView', 'views/ViewingConfirmView', 'views/ValueAddressPropertyListView'],
function(Marionette, HomeView, HeaderView, FooterView, MenuView, VideoView, LocationView, LoginView, FindView, ServicesView, ValueView, PropertyListView, SideBySideView, ConfirmRegistrationView, ForgotPasswordView, CreateAccountView, UserHomeView, MyBrokerView, GiveFeedbackView, SeeFeedbackView, ViewingScheduleView, MyViewingsSummaryView, MyAccountView, ViewingConfirmView, ValueAddressPropertyListView) {
var RootView = Marionette.LayoutView.extend({
...some view code
});
Вариант использования, который я пытаюсь решить:
Поэтому, когда я захожу на сайт в браузере, я замечаю в отладчике, что он загружает все файлы js в самом начале. В процессе загрузки мой сайт пуст, и пользователь должен немного подождать, прежде чем он сможет использовать сайт.
Итак, я смог понять, что когда приложение запускается в main.js, app.js создает экземпляр rootView.js, который, в свою очередь, отображает все представления как зависимости. Это инициирует запрос на загрузку для всех других представлений, который, в свою очередь, разрешит их собственные зависимости и загрузит все соответствующие модели и коллекции. Следовательно, все файлы загружаются, когда пользователь заходит на сайт.
Решение, которое я пытался:
Поскольку используется requirejs, я пытаюсь использовать r.js для оптимизации и объединения всех файлов js, чтобы уменьшить количество скачиваний.
Проблема, с которой я сталкиваюсь:
Когда я бегу r.js. я получаю следующую ошибку
Tracing dependencies for: main
Error: ENOENT: no such file or directory, open '/var/node_projects/rm/rm.src.server/src/public/js/underscore.js'
In module tree:
main
app
Error: Error: ENOENT: no such file or directory, open '/var/node_projects/rm/rm.src.server/src/public/js/underscore.js'
In module tree:
main
app
at Error (native)
Если я добавлю файлы underscore.js непосредственно в указанный путь в ошибке, то получу ту же ошибку для marionette.js. Я думаю, что происходит, что app.js не распознает зависимости shim'ed и, следовательно, пытается найти файлы непосредственно по указанному пути в ошибке.
Вещи, которые я пробовал: - Я добавил wrapShim: true в файл main.build.js, но это не помогло
Честно говоря, я сидел на этом в течение нескольких дней, и я не уверен, что я могу сделать дальше и, следовательно, этот пост.
Любая помощь / направление будет оценено.
1 ответ
Вам нужно включить ту же конфигурацию shim в ваш файл сборки, так как wrapShim недостаточно.
Если в приложении используется конфигурация shim, продублируйте конфигурацию здесь. Необходимо, если используется конфигурация shim, чтобы зависимости shim были включены в сборку. Использование "mainConfigFile" является лучшим способом передачи этой информации, так что она указана только в одном месте. Однако, если mainConfigFile не является опцией, конфигурация shim может быть встроена в конфигурацию сборки.
https://github.com/jrburke/r.js/blob/master/build/example.build.js