Поэтому, в этот раз, я решил рассказать вам свою историю о том, как я выполнял заказ по разработке странички для интернет магазина.
Возможно, вы скажите, что это довольно заезженная тема. Однако, не всё так просто. Если обычно сложности в работу накидывают сами заказчики, то тут я решил сам себе подыскать кочки. Дело в том, что я довольно давно уже отошёл от разработок простых сайтов, страниц и всяких CMS в пользу Single Page Application. Предложение доработать ряд элементов на странице, которая являлась частью уже готового сайта и имела ряд табу в подходе к разработке, не внушало мне особого интереса. Отмечу, что сама задача не сложная. Суть заключалась в том, чтобы выводить товары в соответствующем виде и со своей внутренней логикой. Так же, немаловажное условие было: лёгкое редактирование контента самим заказчиком. Так как сайт сам по себе разработан ни как SPA, то делать это средствами, мною любимого, Angular я не могу… или нет? Да, мне нельзя было подключать к сайту сам fraemwork, но я мог сделать bundle файл со всеми необходимыми мне условиями выполнения задачи.
Сразу скажу, что конечно существуют способы куда проще и правильнее, но в этом случае, я бы не стал браться за эту работу. Мною двигал интерес, в теории я знал, что это сработает. Я читал о неком CodeMix, компоненте, который поставляется с версии Angular 6 и выше. Знакомьтесь, Angular Elements. В двух словах они преобразуют компоненты в элементы HTML (+ JavaScript), позволяя нам использовать наши компоненты в других приложениях, разных fraemworks (тот же, React) или даже в простой странице HTML + JavaScript!
Я не буду описывать заказной вариант работы и в качестве примера приведу простой компонент панели, который будет отображать заголовок и содержимое под ним сообщение. Так же мы разместим, в рамках заголовка, checkbox для контроля за отображением содержимого сообщения. Затем мы продолжим использовать эту панель на простой HTML-странице. Тем самым решив задачу.
По рецепту нам понадобится:
- Node.js,
- Диспетчер пакетов узлов (npm),
- Angular CLI (> 6.0.0),
- CodeMix
В Eclipse создаём новый проект.
File > Create > Project > CodeMix > Angular Project
Далее в терминале для проекта (Ctrl+Shift+P)
Вводим: Terminal: Create New Integrated Terminal
Терминал автоматически откроется в папке проекта. В нём мы вписываем npm install, ng serve. После, спокойно переходим на страницу: localhost:4200. Далее нам нужно задействовать модули Angular element и poly-fills для совместимости браузеров, поскольку они не поддерживаются как надо в браузерах от Microsoft.
npm install @angular/elements @webcomponents/custom-elements
Создадим компонент.
Используя незамысловатые возможности Angular CLI, пишем следующее:
ng g c codemix-example
Наш компонент готов, осталось привести его в порядок.
HTML:
<div class="CodemixExampleComponentClass"> <div class="head"> <span>{{ title }}</span> <input type="checkbox" [checked]="isShow" (change)="changeShow()" /> </div> <div class="body" *ngIf="isShow">{{ content }}</div> </div>
TypeScript:
import { Component, Input, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'codemix-example', templateUrl: './codemix-example.component.html', styleUrls: ['./codemix-example.component.css'], encapsulation: ViewEncapsulation.Native }) export class CodemixExampleComponent { public isShow: boolean; constructor() { } @Input() public content; @Input() public title; public changeShow(): void { this.isShow = !this.isShow; } }
В детали CSS я не буду углубляться, для этого примера я просто задал основным блокам свой цвет фона.
Проверяем наш компонент в том что он работает и продолжаем.
//app.module.ts.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Injector } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { CodemixExampleComponent } from './codemix-example/codemix-example.component'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent, CodemixExampleComponent ], entryComponents: [CodemixExampleComponent], imports: [ BrowserModule ], providers: [] }) export class AppModule { constructor(private injector: Injector){ } ngDoBootstrap(){ const element = createCustomElement( CodemixExampleComponent, { injector: this.injector } ); customElements.define('codemix-example', element) } }
В приведенном выше коде мы остановили Angular от автоматической загрузки приложения. Мы достигли этого, удалив свойство bootstrap в объекте параметра decorator и перезаписав ngDoBootstrap метод в AppModule классе. Мы также добавляем компонент CodemixExampleComponent в массив entryComponents, чтобы инструктировать Angular создавать компонент, даже если он не является частью шаблона. Затем в ngDoBootstrap компонент CodemixExampleComponent анализируется с помощью функции createCustomElement из модуля Angular Elements. Теперь мы можем использовать элемент в HTML-файле в нашем проекте.
Например, index.html файл можно переписать следующим образом:
<!doctype html> ... <body> <div style="width: 50vw; margin: auto;"> <codemix-example title="Title text" content="Content text Content text Content text Content text Content text Content text Content text Content text Content text Content text"> </codemix-example> </div> </body> ...
Получение bundle файла
Теперь, когда мы можем использовать элемент в HTML-документе в нашем проекте, следующим шагом будет создание bundle файла для использования его в качестве зависимости страницы.
Для этого нам понадобиться модуль concat:
npm install concat --save-dev
Остаётся создать скрипт сборки в корне папки проекта.
// build.js:
const concat = require('concat'); const files = [ 'node_modules/@webcomponents/custom-elements/src/native-shim.js', './dist/angulartest/runtime.js', './dist/angulartest/polyfills.js', './dist/angulartest/main.js' ]; const outputFile = './dist/bundle.js'; concat(files, outputFile);
Финальный штрих, запускаем команду, ну или добавляем её в package.json к объекту scripts:
ng build --prod --output-hashing = none && node build-script.js
В итоге мы получили заветный bundle.js. Файл, который теперь может быть использован в любом месте. Скопируйте этот файл в другое место и создайте простой HTML-файл в той же папке.
Если кому интересно на выходе у меня получилось следующее:
А вот и простейший index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Angulartest</title> </head> <body> <div style="width: 50vw; margin: auto;"> <codemix-example title="Title text" content="Content text Content text Content text Content text Content text Content text Content text Content text Content text Content text"> </codemix-example> </div> <script type="text/javascript" src="bundle.js"></script> </body> </html>
Заключение
Как вы видите, мы просто использовали Angular компонент в простом HTML-файле. Да, здорово, что даже в таких задачах Angular способен о себе заявить. Мы способны использовать наш компонент, разработанный на Angular, в React, Vue и т.д., ну не круто ли? Но, как я и сказал в начале, это не единственный и точно не лучший вариант в той задаче, что решал я. Я сделал это только потому что мне было интересно сделать так. Важно знать, что такой способ не полностью поддерживается большинством браузеров. А так же вынуждает нас работать с файлом, который довольно большой для работы с всего лишь одним элементом. Например мой получился в 234КБ.
ссылка на оригинал статьи https://habr.com/post/427075/