Использование Liferay JS Global в локальной среде разработки/тестирования JS - Liferay.ru
Использование Liferay JS Global в локальной среде разработки/тестирования JS
Сегодня на Liferay DevCon кто-то задал мне отличный вопрос:
«Как разработать и протестировать локальный пользовательский элемент (стандартный веб-компонент) при этом используя Liferay глобальный объект JS?»
Мы всё обсудили, и я намекнул, что напишу об этом в блоге. Поскольку я уверен, что другие столкнутся с той же проблемой… вот и всё.
Хорошая новость: это проще, чем вы думаете.
Всё, что вам действительно нужно, — это упрощённая версия объекта Liferay (с достаточным количеством API-интерфейсов, на которые опирается ваш пользовательский элемент), которую можно импортировать во время локальной разработки.
Ниже приведён простой файл Liferay.js, который я использую:
const Liferay = window.Liferay || {
Язык: {
get: (key) => {
return key;
},
},
OAuth2: {
getAuthorizeURL: () => '',
getBuiltInRedirectURL: () => '',
getIntrospectURL: () => '',
getTokenURL: () => '',
getUserAgentApplication: (_serviceName) => {},
},
OAuth2Client: {
FromParameters: (_options) => {
return {};
},
FromUserAgentApplication: (_userAgentApplicationId) => {
return {};
},
fetch: (_url, _options = {}) => {},
},
ThemeDisplay: {
getCompanyGroupId: () => 20119,
getPathThemeImages: () => ",
getPortalURL: () => 'http://localhost:8080',
getScopeGroupId: () => 20117,
getSiteGroupId: () => 20117,
isSignedIn: () => false,
},
authToken: ",
вкл.: (_event, _callback) => {},
запуск: (_event, _data) => {},
};
По умолчанию используется Liferay.
This is not the complete Liferay global object; Liferay’s real runtime includes many more fields and service APIs, but this stub is perfect for local development and testing for the component I was working on at the time.
I included only the pieces I needed:
Liferay.Language.get()Liferay.ThemeDisplayfields for companyId, groupId, portal URL, etc.Liferay.OAuth2+Liferay.OAuth2Client- Event helpers (
on,fire) authToken
Если бы завтра мне понадобилось что-то вроде Liferay.Session.extend(), я бы просто добавил ещё одну заглушку в тот же файл.
Версия машинописного текста
Если вы используете TypeScript, вот версия, которую можно вставить в liferay.ts:
interface LiferayType {
Language: {
get: (key: string) => string;
};
OAuth2: {
getAuthorizeURL: () => string;
getBuiltInRedirectURL: () => string;
getIntrospectURL: () => string;
getTokenURL: () => string;
getUserAgentApplication: (serviceName: string) => unknown;
};
OAuth2Client: {
FromParameters: (options: Record<string, unknown>) =>
unknown;
FromUserAgentApplication: (userAgentApplicationId: string)
=> unknown;
fetch: (url: string, options?: Record<string, unknown>) =>
unknown;
};
ThemeDisplay: {
getCompanyGroupId: () => number;
getPathThemeImages: () => string;
getPortalURL: () => string;
getScopeGroupId: () => number;
getSiteGroupId: () => number;
isSignedIn: () => boolean;
};
authToken: string;
on: (событие: строка, обратный вызов: (...args: unknown[]) => void)
=> void;
fire: (событие: строка, данные?: unknown) => void;
}
const Liferay: LiferayType =
(окно как любое другое).Liferay ||
({
Язык: {
get: (key: string) => key,
},
OAuth2: {
getAuthorizeURL: () => '',
getBuiltInRedirectURL: () => '',
getIntrospectURL: () => '',
getTokenURL: () => '',
getUserAgentApplication: (_serviceName: string) => {},
},
OAuth2Client: {
FromParameters: (_options: Record<string, unknown>) =>
({}),
FromUserAgentApplication: (_id: string) => ({}),
fetch: (_url: string, _options?: Record<string, unknown>)
=> {},
},
ThemeDisplay: {
getCompanyGroupId: () => 20119,
getPathThemeImages: () => ",
getPortalURL: () => 'http://localhost:8080',
getScopeGroupId: () => 20117,
getSiteGroupId: () => 20117,
isSignedIn: () => false,
},
authToken: ",
on: (_event: строка, _callback: (...аргументы: неизвестны[]) =>
void) => {},
запуск: (_event: строка, _data?: неизвестно) => {},
} как LiferayType);
По умолчанию используется Liferay.
Он окажется для вас очень полезным, поскольку содержит типобезопасное определение объекта среды выполнения, которого в Liferay нет.
Добавление недостающих заглушек в версию на TypeScript требует немного больше усилий.
Поскольку TypeScript обеспечивает соблюдение структуры, вам нужно убедиться, что ваш интерфейс соответствует реальному глобальному объекту Liferay или, по крайней мере, тем его частям, которые фактически использует ваш компонент. Это означает:
- Соответствующие сигнатуры методов (например, какие параметры
Liferay.OAuth2Client.fetch()ожидает) - Совпадающие возвращаемые типы
- Включая все вложенные сервисы или пространства имён ваш компонент зависит от
Если вы допустите ошибку, ваш компонент может пройти локальную проверку типов, но при развертывании в Liferay будут возникать ошибки.
Так где же найти настоящие определения? Самый простой способ, который я нашёл, — использовать консоль браузера: Открыть DevTools → ввести Liferay → развернуть. Я знаю, это может показаться странным, но если посмотреть на исходный код Liferay, то можно увидеть, что JS-код разбросан по всему коду и объединяется во время выполнения, поэтому бывает сложно найти нужные фрагменты.
Вам не нужно копировать весь объект, достаточно того, что ваш компонент будет работать локально с соблюдением типобезопасности.
Подведение Итогов
Этот небольшой шаблон, простая заглушка Liferay.js (или liferay.ts) оказалась невероятно полезной для меня при создании локальных пользовательских элементов, которые зависят от глобального объекта Liferay.
Это позволяет мне:
- Разрабатывайте и тестируйте локально на полной скорости
- Не создавайте портал каждый раз заново
- Используйте синтаксис
||, чтобы моя заглушка работала локально, но при развёртывании автоматически ссылалась на реальнуюwindow.Liferayзаглушку
Кратко и ясно, но очень практично.
Если вы когда-либо сталкивались с трудностями при локальной разработке пользовательских элементов, интегрированных в Liferay, надеюсь, эта статья немного облегчит вам жизнь.