Как реализовать базовое приложение на JavaScript

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

Над чем мы работаем?

Цель этой серии — показать все аспекты современного фронтенд-приложения на JavaScript на максимально простом примере:

Встроенный JavaScript

Первый шаг — нам нужно сделать так, чтобы какая-то часть нашего HTML-прототипа выполнялась с помощью JavaScript. Самый простой способ сделать это — использовать inline JS. Итак, наш index.html становится:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Hello World!</title>
  </head>
  <body>
    <script type="text/javascript">
      const element = document.createElement("h1");

      element.innerText = "Hello World!";

      document.body.appendChild(element);
    </script>
  </body>
</html>
Вход в полноэкранный режим Выход из полноэкранного режима

Если вам интересно, что здесь произошло и как получается та же страница, что и раньше, вы можете прочитать больше о манипуляции DOM здесь.

Загрузка JS-файла

Размещение всего кода в файле index.html не приведет к масштабированию — это очень быстро станет неудобным. Вместо этого давайте разобьем наш код на отдельные HTML и JS файлы:

script.js:

const element = document.createElement("h1");

element.innerText = "Hello World!";

document.body.appendChild(element);
Вход в полноэкранный режим Выход из полноэкранного режима

и обновленный index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Hello World!</title>
  </head>
  <body>
    <script type="text/javascript" src="./script.js"></script>
  </body>
</html>
Вход в полноэкранный режим Выход из полноэкранного режима

Это намного лучше!

Модуль JavaScript

В предыдущем шаге мы включили JavaScript традиционным способом — по одному файлу за раз. Современный JS позволяет нам писать код в модулях, которые определяют свои зависимости внутри, а браузеры сами определяют пути и загружают необходимые файлы. На данный момент эта возможность уже доступна почти в 95% браузеров на рынке (источник).

Давайте используем это в нашем приложении!

Сначала мы перенесем сообщение в отдельный файл greeting.js:

export const greetingMessage = "Hello World!";
Вход в полноэкранный режим Выход из полноэкранного режима

Обратите внимание, что мы используем export перед const greetingMessage.... Это дает понять JS, что эта константа должна быть доступна для импорта из других файлов.

Теперь мы можем легко импортировать это значение в любое место нашего проекта. Мы сделаем то же самое для обновленного script.js:

import { greetingMessage } from "./greeting.js";

const element = document.createElement("h1");

element.innerText = greetingMessage;

document.body.appendChild(element);
Вход в полноэкранный режим Выход из полноэкранного режима

Наименее необходимым обновлением является изменение атрибута type в импорте в index.html:

     <title>Hello World!</title>
   </head>
   <body>
-    <script type="text/javascript" src="./script.js"></script>
+    <script type="module" src="./script.js"></script>
   </body>
 </html>
Вход в полноэкранный режим Выход из полноэкранного режима

Вы можете прочитать больше о нативных ES-модулях в этой статье.

Превращение в пакет npm

npm — это менеджер пакетов, который позволяет нам легко загружать пакеты сообщества для использования в нашем приложении. Он был создан для Node, серверной части JavaScript, но несколько лет назад он стал стандартом и для фронтенд-части JavaScript. В нашем случае он позволит просто настроить сценарий сборки и зависимости сборки.

Чтобы инициализировать пакет, вы можете запустить npm init в папке с пакетом:

$ npm init
This utility will walk you through creating a `package.json` file.
It covers only the most common items, and it tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (hello-world)
version: (1.0.0)
…
Вход в полноэкранный режим Выйти из полноэкранного режима

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

Webpack

Использование собственных ES-модулей работает в большинстве браузеров, но в реальных проектах вы все равно увидите, что JS подключается как часть процесса сборки. Почему? Есть много вещей, которые вы обычно хотите сделать в проекте:

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

Более подробно я обсуждаю причины здесь.

Самым популярным JS бандлером для JavaScript является Webpack. Давайте добавим его в наш проект! Сначала нам нужно установить его:

$ npm install webpack --save-dev

added 77 packages, and audited 78 packages in 7s

9 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Войти в полноэкранный режим Выйти из полноэкранного режима

В случае успеха эта команда загрузит файлы webpack и добавит их в зависимости разработки в package.json.

Игнорирование Git

Если вы используете git-as, вам следует установить это значение в .gitingore:

node_modules
dist
Войти в полноэкранный режим Выйти из полноэкранного режима

Это сохранит обе папки вне репозитория:

Build

Чтобы начать использовать webpack, в том же файле package.json добавим build в раздел scripts:

{
  …
  "scripts": {
    "build": "webpack --mode production",
    …
  },
Вход в полноэкранный режим Выход из полноэкранного режима

--mode production явно устанавливает способ, которым Webpack должен собирать код — так мы можем избежать появления следующих предупреждений в консоли:

WARNING in configuration
The 'mode' option has not been set, webpack will fall back to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
Войти в полноэкранный режим Выход из полноэкранного режима

Мы запускаем сборку с помощью npm run build. При первом запуске будут установлены некоторые дополнительные зависимости:

$ npm run build

> hello-world@1.0.0 build
> webpack

CLI for webpack must be installed.
  webpack-cli (https://github.com/webpack/webpack-cli)

We will use "npm" to install the CLI via "npm install -D webpack-cli".
Do you want to install 'webpack-cli' (yes/no): yes
Войти в полноэкранный режим Выход из полноэкранного режима

Первая сборка завершится неудачей, потому что конфигурация webpack по умолчанию ищет код в папке ./src. Мы можем исправить это:

  • переименование script.js в index.js,
  • переместим оба файла index.js и greeting.js в новую папку ./src.

Чтобы использовать наш собранный код, давайте обновим index.html со следующим изменением:

    <title>Hello World!</title>
   </head>
   <body>
-    <script type="module" src="./script.js"></script>
+    <script src="./dist/main.js"></script>
   </body>
 </html>
Вход в полноэкранный режим Выйти из полноэкранного режима

Вы можете найти мой код на этом этапе здесь.

Генерация index.html

Некоторые JS бандлеры используют индексные файлы в качестве конфигурации для определения того, какие файлы должны быть собраны. В Webpack обычно все наоборот: конфигурационный файл отвечает за определение того, как должен быть сгенерирован индексный файл. Поначалу это может быть немного запутанным, но это хорошо работает, когда мы переходим к серверу разработки на следующем шаге. Так что давайте настроим его здесь!

Добавление webpack.config.js

Сначала мы добавим файл конфигурации webpack.config.js:

module.exports = {
  mode: "production",
};
Вход в полноэкранный режим Выход из полноэкранного режима

Это изменение позволяет нам упростить сценарий сборки в package.json:

  "scripts": {
-    "build": "webpack --mode production",
+    "build": "webpack",
     "test": "echo "Error: no test specified" && exit 1"
   },
Войти в полноэкранный режим Выйти из полноэкранного режима

поскольку режим уже задан в конфигурации. На этом этапе сборка должна работать так же, как и раньше.

Код примера.

Добавление html-webpack-plugin

Далее нам нужно добавить еще одну зависимость для разработки:

$ npm install --save-dev html-webpack-plugin
Вход в полноэкранный режим Выход из полноэкранного режима

Чтобы использовать его, нам нужно обновить webpack.config.js до:

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "production",
  plugins: [new HtmlWebpackPlugin({ title: "Hello World!" })],
};
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь удалите старый index.html.

В результате окончательной сборки будет создано два файла:

$ npm run build

> hello-world@1.0.0 build
> webpack

asset index.html 215 bytes [emitted]
asset main.js 116 bytes [compared for emit] [minimized] (name: main)
orphan modules 47 bytes [orphan] 1 module
./src/index.js + 1 modules 218 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 157 ms
Вход в полноэкранный режим Выход из полноэкранного режима

и его результат можно найти в папке dist:

$ ls dist
index.html      main.js
Enter fullscreen mode Выход из полноэкранного режима

Посмотрите на код для сравнения.

Сервер разработки

Чтобы помочь в разработке, Webpack предоставляет сервер разработки.

Почему мы должны беспокоиться? Сервер разработки:

  • следит за изменениями файлов
  • перестраивается каждый раз, когда что-то изменяется
  • перезагружает приложение в вашем браузере

Он легко сэкономит вам несколько секунд каждый раз, когда вы вносите изменения в код — а это может быть сотни раз в течение рабочего дня.

Его легко настроить: просто добавьте скрипт start в package.json:

  "main": "src/index.js",
   "scripts": {
     "build": "webpack",
+    "start": "webpack serve",
     "test": "echo "Error: no test specified" && exit 1"
   },
Вход в полноэкранный режим Выйти из полноэкранного режима

При первом запуске этой команды Webpack предложит установить необходимую зависимость-webpack-dev-server:

$ npm run start

> hello-world@1.0.0 start
> webpack serve

[webpack-cli] For using the 'serve' command you need to install: 'webpack-dev-server' package.
[webpack-cli] Would you like to install the 'webpack-dev-server' package? (That will run 'npm install -D webpack-dev-server') (Y/n) Y
Войти в полноэкранный режим Выйти из полноэкранного режима

Давайте посмотрим на это в действии:

$ npm run start

> hello-world@1.0.0 start
> webpack serve

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
…
Вход в полноэкранный режим Выход из полноэкранного режима

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

Ознакомьтесь с эталонным кодом.

Хотите узнать больше о webpack?

У меня есть курс по webpack, доступный на Udemy. Там вы найдете аналогичный пошаговый подход.

Поделитесь своим проектом

Надеюсь, технический поворот не отпугнул вас, и вы продолжаете работать над своим проектом! Поделитесь в комментариях своими успехами или трудностями.

Оцените статью
devanswers.ru
Добавить комментарий