null

Liferay 7.0 + OpenLayers: "ol is not defined"

На главной странице нашего сайта есть карта, для отрисовки которой используется библиотека OpenLayers. После миграции с Liferay 6.2 на Liferay 7.0, карта перестала отрисовывать, а в логах появилась ошибка:  Uncaught ReferenceError: ol is not defined

Проблема связана с тем, что в новой версии портала введен загрузчик модулей AMD (Liferay AMD Module Loader).

Асинхронное определение модуля (англ. asynchronous module definition, AMD) — это подход к разработке на Javascript, при котором модули и их зависимости могут быть загружены асинхронно.
(с) Википедия

Ниже приведён фрагмент файла ol.js.

(function (root, factory) {
  if (typeof exports === "object") {
    module.exports = factory();
  } else if (typeof define === "function" && define.amd) {
    define([], factory);
  } else {
    root.ol = factory();
  }
}(this, function () {

Простой отладочный вывод показал, что выполняется вторая ветка кода и переменная ol действительно не объявляется. Но так как мы используем OpenLayers не в режиме JS-модуля, это приводило к ошибке.

В простом варианте можно просто убрать лишние ветки if или сделать так, чтобы условие не выполнялось.

(function (root, factory) {
  if (typeof exports === "object") {
    module.exports = factory();
  } else if (false && typeof define === "function" && define.amd) {
    define([], factory);
  } else {
    root.ol = factory();
  }
}(this, function () {

Другой способ исправить проблему без модификации сторонних скриптов, аналогичный предложенному тут, заключается во временном отключении AMD Loader. Для это создаём два скрипта:

disable_amd.js

if (typeof define === 'function' && define.amd) {
    define._amd = define.amd; 
    delete define.amd;
}

и enable_amd.js.

if (typeof define === 'function' && define._amd) {
  define.amd = define._amd; 
  delete define._amd;
}

И помещаем загрузку наших модулей между ними.

<script type="text/javascript" src="https://path/to/js/disable_amd.js"></script>
<script type="text/javascript" src="https://path/to/js/ol.js"></script>
<script type="text/javascript" src="https://path/to/js/enable_amd.js"></script>


И, наконец, согласно официальной документации AMD загрузчик можно отключить совсем. Для этого нужно перейти в Control Panel > Configuration > System Settings > вкладка Foundation > JavaScript Loader и снять галочку Expose Global. Это работает для версий Liferay Portal CE 7.0 GA4, Liferay Digital Enterprise 7.0 SP2 (Fix Pack 8) и выше.