Как изменить порядок, в котором Meteor загружает файлы Javascript?
Когда вы создаете проект с фреймворком Meteor, он объединяет все файлы вместе, но, похоже, не существует способа явно указать "Я хочу, чтобы этот файл загружался до этого".
Скажем, например, у меня есть 2 файла javascript: foo.js
и bar.js
.
Файл bar.js
на самом деле содержит код, зависящий от одного внутри foo.js
, но Meteor загружает bar.js
до foo.js
, разбивая проект.
- В node.js я просто использовал бы
require('./bar')
внутри foo.js
- В браузере я бы поставил тег
<script>
, указывающий на foo.js
, а другой, после, указав на bar.js
, чтобы загрузить файлы в правильном порядке.
Как мы можем это сделать в Meteor?
Ответы
Ответ 1
В соответствии с документацией Meteor файлы в настоящее время загружаются в следующем порядке:
- Сначала загружаются файлы в [project_root]/lib
- Файлы сортируются по глубине каталога. Сначала загружаются более глубокие файлы.
- Файлы сортируются в алфавитном порядке.
- main. * файлы загружаются последними.
Источник:
http://docs.meteor.com/#structuringyourapp
Ответ 2
Не решение для всех сценариев, но я думаю, что в идеале все, что зависит от другого кода, будет помещено в функцию Meteor.startup, чтобы гарантировать, что все уже загружено.
Ответ 3
Вы всегда можете найти JS-загрузчик, например yepnope.js и добавить его в файл client.js. Это работает для меня.
Ответ 4
У меня есть набор функций полезности, которые я структурировал под общим пространством имен (js global).
т.е.
// utils/utils.js
Utils = {};
а затем в подпапках:
// utils/validation/validation.js
Utils.Validation = {};
// utils/validation/creditCard.js
Utils.Validation.creditCard = ... // validation logic etc
Также у меня есть куча кода, который использует Utils и его подобъекты.
Очевидно, что эта структура не работает как вложенные подпапки Meteor в первую очередь.
Чтобы он работал должным образом, мне пришлось создать/подпапку/подпапку/подпапку с бессмысленными именами, а затем перетащить корневой объект в самую глубокую подпапку и объекты ветвей в подпапках, которые не настолько глубоки.
Это очень противоречиво для моего вкуса и склонности к ошибкам (предположим, что у вас есть компонент, который еще глубже в структуре папок).
Чтобы решить эту проблему, я использовал библиотеку Q с defers и promises. Решение по-прежнему не является чистым, так как оно заставляет вас повторять и проверять обычный код, но он дает вам полный контроль над порядком загрузки, не вникая в структуру каталогов (привет людям, которые говорят, что вы можете организовать метеоритный код по своему усмотрению).
Пример:
//utils.js
UtilsDefer = UtilsDefer || Q.defer();
UtilsDefer.resolve({
// here some root utils stuff
});
//cards.js
// here we'll depend on Utils but don't want to care about directory structure
UtilsDefer = UtilsDefer || Q.defer(); // it will be a) already
// resolved defer from utils.js, or b) new defer that will
// be resolved later in utils.js
UtilsDefer.then(function(Utils) {
// do something with utils usage, or for instance add some fields here
Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
Utils.CreditCardDefer.resolve({
// Credit card utils here
})
});
//someOtherFile.js
// it will be pain to use sub-objects with this method though:
UtilsDefer = UtilsDefer || Q.defer();
UtilsDefer.then(function(Utils) {
Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
Utils.CreditCardDefer.then(function(CreditCard) {
// do stuff with CreditCard _if_ you need to do it on startup stage
})
});
Это пример довольно узкого использования, так как в основном вы будете довольны обработкой этих глобалов внутри некоторых обратных вызовов взаимодействия с пользователем или Meteor.startup
, где все уже инициализировано. В противном случае, если вы хотите получить мелкий контроль над порядком инициализации на очень ранней стадии, это может быть решением.