История одной разработки

Хотя прошлая моя публикация была замечена рядом людей, тем не менее она получила клеймо «Перевода». Что без сомнений делает все мои рекомендации, отмеченные там, плагиатом. Ведь не существует единого мнения по ведению кода.

Поэтому, в этот раз, я решил рассказать вам свою историю о том, как я выполнял заказ по разработке странички для интернет магазина.

Возможно, вы скажите, что это довольно заезженная тема. Однако, не всё так просто. Если обычно сложности в работу накидывают сами заказчики, то тут я решил сам себе подыскать кочки. Дело в том, что я довольно давно уже отошёл от разработок простых сайтов, страниц и всяких 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/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *