Компилятор Ангуляр в 200 строчек кода

Автор: admin от 15-04-2019, 11:20, посмотрело: 24

Привет. Меня зовут Роман, и я не изобретатель велосипедов. Мне нравится фреймворк Angular и экосистема вокруг него, и я разрабатываю с его помощью свои веб-приложения. С моей точки зрения, основное преимущество Angular в долгосрочной перспективе базируется на разделении кода между HTML и TypeScript, что подробно было описано одним из его разработчиков why-angular-renders-components-with.html Это преимущество имеет и обратную сторону: необходимость компиляции в принципе и сложность динамической компиляции компонентов в runtime. А так хочется использовать уже знакомый синтаксис шаблонов Angular, чтобы дать пользователю своих приложений возможность настраивать шаблоны писем, генерировать отчеты и таблицы для печати или задавать формат экспорта xml файлов! Чтобы узнать, как это сделать — добро пожаловать под кат!

3D проект вашего заказа

Для редактирования проекта пройдите по ссылке Редактировать


[/code]

Библиотека ng-template



Эту задачу можно решить использованием компилятора Angular на клиентской (или даже серверной стороне), но это весьма трудоёмко и потребует притащить много мегабайт кода на клиент. Почему же компилятор Angular такой большой? Это связано с тем, что он поддерживает море разнообразного функционала для композиции компонентов и модулей, а также содержит собственный парсер HTML! Поэтому я решил написать минимальный преобразователь шаблонов Angular, который будет использовать встроенный в браузер парсер HTML. Это удалось сделать всего лишь в 200 с небольшим строчек кода за пару часов. Результатом я решил поделиться с общественностью на GitHub



Использовать библиотеку ng-template довольно просто:



Устанавливаем зависимость из npm



npm install --save @quanterion/ng-template


или через yarn



yarn add @quanterion/ng-template


И используем следующим образом:



import { compileTemplate, htmlToElement } from '@quanterion/ng-template';

async test() {
  let data = { name: 'Roman' };
  let element = htmlToElement(`<div>{{name}}</div>`);
  await compileTemplate(element, data);
  alert(element.outerHTML);
}


Поддерживаемый синтаксис




  1. Выражения {{expression}} с возможностью доступа к переменным и вызова функций

  2. Шаблоны ng-template

  3. Контейнеры ng-container

  4. Условия *ngIf + *ngIf as

  5. Циклы *ngFor

  6. Стили [style.xxx]=«value» и [style.xxx.px]=«value»

  7. Условные классы [class.xxx]=«value»

  8. Observables {{name$}} c автоматической подпиской на значение (как пайп async)



Подробнее смотрите в тестах ng-template.spec.ts



Использование Eval



Для вычисления выражений в шаблонах используется eval с преферансом и куртизанками. Дело в том, что в шаблонах Angular доступ к переменным используется без привычного для javascript префикса this. Поэтому требуется вызвать eval(), у которого в области видимости лежат все переменные из объекта с данными. Сгенерировать такой код для eval() у меня не получилось, т.к. код вида



const data = { a: 1, b: () => 4 };
const expression = 'a+b()';
eval('a =1; b = ??;' + expression);


не позволяет передать функции



Решение было найдено путем создания функции, у которой параметры имеют имена полей объекта с данными:



const data = { a: 1, b: () => 4 };
let entries = []
for (let property in data ) {
  entries.push([property, data[property]])
}
const params = entries.map(e => e[0]);
const fun = new Function('code', ...params, `return eval(code)`);
const args = entries.map(e => e[1]);
const expression = 'a+b()';
const result = fun.call(undefined, expression , ...args);


P.S.: Я надеюсь в будущем, когда API нового компилятора Ivy стабилизируется, можно будет генерировать набор операторов для Ivy и создавать полноценные компоненты в динамике!



Ссылка на исходники

Источник: Хабр / Интересные публикации

Категория: Веб-разработка

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *