Создайте базовую библиотеку JavaScript с нуля

Что общего у React и Angular, помимо того, что они являются двумя крупнейшими фреймворками / библиотеками для веб-разработки?

Они оба основаны на компонентах!

В этой статье мы создадим простую интерфейсную библиотеку, которая использует компоненты со старым добрым простым JavaScript. Это может помочь нам немного лучше понять компоненты, а также отточить наши навыки в простом JavaScript.

Предварительные требования

Прежде чем мы сможем погрузиться в часть этой статьи, посвященную JavaScript, нам необходимо настроить структуру нашего проекта. Для этого мы создаем новую папку с именем component-library и еще несколько подпапок и файлов:

$ mkdir component-library
$ cd ./component-library
$ mkdir lib style components
$ touch index.html index.js ./style/styles.css

Далее нам нужно заполнить наши файлы HTML и CSS следующим образом:

Теперь мы все настроены и готовы написать немного JavaScript.

Библиотека под названием Eszett

Мне нравится начинать с представления, что библиотека уже существует. Поэтому первое, на чем нам нужно сосредоточиться, - это index.js.

В самом верху файла нам нужно импортировать нашу библиотеку, а затем создать экземпляр нового приложения:

// All our imports are here
import ß from ‘./lib/Eszett.js’;
// Initialize app
const app = new ß('app');

Этот код вызовет ошибку, потому что мы ничего не экспортировали из нашего Eszett.js. В этом файле нам нужен класс ß с конструктором, который принимает селектор как строку и экспортирует ее. Итак, прежде всего нам нужно создать такой файл:

$ touch ./lib/Eszett.js

Содержимое этого файла должно выглядеть так:

class ß {
  constructor(selector) {
    this.eszettElement = document.querySelector(`#${selector}`);
    console.log(‘Eszett initialized!’);
  }
}
export default ß;

Если вы запустите приложение сейчас, мы больше не получим ошибку, и в консоли вашего браузера должен появиться текст «Eszett initialized». Но пока мы мало что делаем с нашим кодом. Давайте изменим это, реализовав возможность регистрировать компоненты в нашем приложении.

Компоненты

Чтобы это работало, нам нужно реализовать две вещи:

  • поле для хранения всех зарегистрированных компонентов
  • метод registerComponent

Сначала мы добавляем следующую строку в конструктор прямо над console.log:

this.components = {};

Планируется зарегистрировать все компоненты в этом поле как пары ключ-значение. Для этого нам нужно добавить следующий метод под конструктором:

registerComponent(component {
  this.components[component.name] = component;
}

Теперь мы можем зарегистрировать компоненты в нашем приложении. Регистрация будет происходить в index.js прямо под инициализацией нашего приложения. Нашим первым компонентом будет MenuComponent. Это будет двухэтапный процесс: сначала мы импортируем компонент, а затем регистрируем его после инициализации приложения.

После этого наш index.js должен выглядеть так:

// All our imports are here
import ß from ‘./lib/Eszett.js’;
import MenuComponent from ‘./components/MenuComponent.js’;
// Initialize app
const app = new ß(‘app’);
// Adding our Components to the App
app.registerComponent(MenuComponent)

В настоящий момент наше приложение выдает ошибку, потому что у нас еще нет MenuComponent, теперь мы продолжим и создадим его, добавив новый файл, подобный этому:

$ touch ./components/MenuComponent.js

В этот файл мы импортируем наш еще не существующий Component.js, чтобы мы могли создать новый компонент. После этого нам понадобится HTML-шаблон и, наконец, что не менее важно, сам компонент. Вот как это должно выглядеть:

Давайте сначала подробнее рассмотрим HTML-шаблон. Это функция, которая возвращает шаблонный литерал (строку шаблона) и получает состояние компонента, переданного в качестве параметра. В строке 8 мы видим, что это состояние используется для динамического отображения имени блога.

Взглянув на сам компонент, мы видим, что он передается с тремя параметрами. Первый параметр - это имя самого компонента, второй параметр - объект с единственным атрибутом с именем name. Это объект состояния, который мы передаем нашему menuTemplate, который также является нашим последним параметром.

Чтобы все это работало, нам нужно реализовать наш component.js. Во-первых, нам нужно создать такой файл:

$ touch ./lib/Component.js

Реализация нашего компонента проста. Нам нужен конструктор, который принимает три параметра, и нам нужна функция, которая вызывает нашу HTML-Template-Function и возвращает ее результат. В конце должно получиться так:

Теперь наша страница не будет показывать никаких ошибок, но и не будет отображать наш MenuComponent.

Рендеринг

Мы можем создать компонент и зарегистрировать его в нашем приложении, но мы не можем отображать HTML компонентов. Прежде чем мы займемся этой проблемой, я хочу добавить в наше приложение PostComponent, чтобы мы могли одновременно отображать два компонента.

Для этого нам нужно зарегистрировать его так:

Создать это:

$ touch ./components/PostsComponent.js

И реализуем это так:

Чтобы рендеринг работал, нам нужно обновить DOM, вызвав метод view наших компонентов и вставив возвращенный HTML в уже определен eszettElement. Описанное поведение должно быть одним из методов нашего ß класса и вызываться внутри нашего метода registerComponent. Это последняя реализация нашего класса:

Метод updateView сначала проверяет, есть ли какие-либо зарегистрированные компоненты. Если это так, он выполняет итерацию по всем компонентам и вызывает метод view для каждого из них. Возвращенный HTML будет объединен и установлен в innerHTML элемента eszettElement. Если все получилось, ваша последняя страница должна выглядеть так:

Что может быть дальше?

Мы только что создали нашу небольшую библиотеку под названием Eszett. Мы можем создавать компоненты, содержащие изолированное состояние и собственные HTML-шаблоны. Эти компоненты могут быть зарегистрированы и отображены на уровне приложения.

Мы могли бы добавить еще несколько функций. Например, маршрутизатор, который отображает определенные компоненты на определенных маршрутах, или возможность вложить компонент в другой компонент и передать состояние.

Просто попробуйте добавить к нему новые функции, чтобы отточить свои навыки JavaScript, и пока вы этим занимаетесь, получайте удовольствие!

Как всегда, вы можете найти код этого проекта на моем GitHub.

Уровень кодирования

Спасибо, что стали частью нашего сообщества! Подпишитесь на наш канал YouTube или присоединитесь к Интервью по программированию Skilled.dev.