Доступ к объекту `goog.require`d в библиотеке закрытия без компиляции
Я экспериментирую с библиотекой Google Closure и прорабатываю официальное руководство по XhrIo. Я столкнулся с некоторыми проблемами с xhr-quick2.js
Пример, воспроизведенный ниже:
goog.require('goog.net.XhrIo');
var xhr = new goog.net.XhrIo();
goog.events.listen(xhr, goog.net.EventType.COMPLETE, function(e) {
obj = this.getResponseJson();
log('Received Json data object with title property of "' +
obj['title'] + '"');
alert(obj['content']);
});
function getData(dataUrl) {
log('Sending simple request for ['+ dataUrl + ']');
xhr.send(dataUrl);
}
При запуске я получаю сообщение об ошибке:
Uncaught TypeError: Невозможно прочитать свойство 'XhrIo' из неопределенного
Если я переместить слушатель события и экземпляр XHR в пределах getData
функция (которая вызывается в организме onload
), все хорошо.
goog.require('goog.net.XhrIo')
function getData(dataUrl) {
var xhr = new goog.net.XhrIo()
goog.events.listen(xhr, goog.net.EventType.COMPLETE, function(e) {
obj = this.getResponseJson()
log(`Received Json data object with title property of "${ obj["title"] }"`)
alert(obj["content"])
})
log(`Sending simple request for [${ dataUrl }]`)
xhr.send(dataUrl)
}
function log(msg) {
document.getElementById('log').appendChild(document.createTextNode(msg));
document.getElementById('log').appendChild(document.createElement('br'));
}
Я предполагаю, что это потому, что goog.require
не закончил импорт net
когда goog.net.XhrIo
создается в строке 3 первого примера кода. Я полагаю, что идеальным решением является запуск всего моего кода через компилятор замыкания, но я просто экспериментирую, и другие части документации предполагают, что мой рабочий процесс приемлем для разработки.
Есть ли что-нибудь, что я могу вручную найти в моем html, чтобы устранить эту проблему? Есть ли какой-то другой подход, который я должен использовать?
2 ответа
Прошло несколько лет с тех пор, как я в последний раз играл с замыканием, но я не думаю, что вы можете просто использовать require без компилятора зависимостей.
Закрытие работает путем сканирования ваших файлов JavaScript для goog.module
а также goog.require
написать deps.js
файл. Этот файл должен быть загружен в первую очередь перед вашими файлами JavaScript. Он перечисляет все модули, используемые кодом, и загружает их в правильном порядке.
Если deps.js
приходит первым, потом goog.net
будет загружен в тот момент, когда он попадет в ваш код. Код goog.require('goog.net.XhrIo')
в строке 1 будет игнорироваться.
Согласно документам goog.require
вставит <script>
тег после текущего <script>
выполняется Так что если вы хотите пропустить шаг использования deps.js
тогда вам придется обернуть все в документ, готовый к обратному вызову, или добавить вручную goog.require
в файл JavaScript, который загружается перед вашим кодом.
Я думаю, что это не стоит усилий и проще просто использовать средство записи зависимостей замыкания для создания deps.js
файл.
Здесь есть краткое руководство:
https://www.safaribooksonline.com/library/view/closure-the-definitive/9781449381882/ch01.html
Вот CLI для написания deps.js
файл:
python ../closure-library/closure/bin/calcdeps.py \
--dep ../closure-library \
--path my_stuff.js \
--output_mode deps > deps.js
Для некомпилированного режима требуемый документ должен быть предварительно загружен. Таким образом, в вашем HTML-документе вы должны иметь:
<!DOCTYPE html>
<html>
<head>
<script src="path/to/closure/base.js"></script>
<script>
goog.require('goog.net.XhrIo');
</script>
<script src="mysource.js"></script>
</head>
</html>
Любые зависимости должны быть загружены в отдельный тег скрипта. Тогда ваши примеры кода выше должны работать.