Статьи

Используйте Parcel для объединения приложений Hyperapp и развертывания на страницах GitHub

В предыдущем посте мы познакомились с Hyperapp, крошечной библиотекой, которую можно использовать для создания динамических одностраничных веб-приложений аналогично React или Vue.

В этом посте мы собираемся сделать вещи на ступеньку выше. Мы собираемся создать приложение локально (мы работали над CodePen ранее), узнаем, как связать его с помощью Parcel (пакетный модуль, похожий на webpack или Rollup) и развернуть его в Интернете с помощью GitHub Pages .

Не беспокойтесь, если вы не завершили проект с первого поста. Весь код предоставлен здесь (хотя я не буду подробно объяснять, что он делает), и изложенные принципы могут быть применены к большинству других проектов JavaScript.

Если вы хотите посмотреть, чем мы закончим, вы можете просмотреть готовый проект здесь или загрузить код из нашего репозитория GitHub .

Основные настройки

Чтобы продолжить, вам нужно установить Node.js и npm (они упакованы вместе). Я бы порекомендовал использовать менеджер версий, такой как nvm, для управления установкой Node ( вот как ), и если вам нужна помощь в освоении npm, ознакомьтесь с нашим удобным для начинающих руководством по npm .

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

Для начала создайте новую папку с именем hyperlist :

 mkdir hyperlist 

Теперь перейдите в этот каталог и инициализируйте новый проект, используя npm:

 cd hyperlist/ npm init 

Это побудит вас ответить на несколько вопросов о приложении. Это нормально, просто нажмите Enter, чтобы принять значение по умолчанию для любого из них, но вы можете добавить свое имя как автора и добавить описание приложения.

Это должно создать файл с именем package.json внутри каталога hyperlist который выглядит примерно так:

 { "name": "hyperlist", "version": "1.0.0", "description": "A To-do List made with Hyperapp", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "DAZ", "license": "MIT" } 

Теперь нам нужно установить библиотеку Hyperapp. Это делается с помощью npm вместе с флагом --save , что означает, что файл package.json будет обновлен, чтобы включить его в качестве зависимости:

 npm install --save hyperapp 

Это может дать некоторые предупреждения об отсутствии поля репозитория. Не беспокойтесь об этом, так как мы исправим это позже. Он должен обновить файл package.json включив в него следующую запись (может быть небольшая разница в номере версии):

 "dependencies": { "hyperapp": "^1.2.5" } 

Он также создаст каталог с именем node_modules котором node_modules все файлы Hyperapp, а также файл с именем package-lock.json . Это используется для отслеживания дерева зависимостей для всех пакетов, которые были установлены с использованием npm.

Теперь мы готовы начать создавать приложение!

Структура папок

Общепринято помещать весь ваш исходный код в папку с именем src . В этой папке мы собираемся поместить все наши файлы JavaScript в каталог с именем js . Давайте создадим оба из них сейчас:

 mkdir -p src/js 

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

 cd src/js touch state.js actions.js view.js 

Не беспокойся, что все они пусты. Мы скоро добавим код!

И наконец, мы вернемся в каталог src и создадим файлы «точки входа». Это файлы, которые будут ссылаться на все остальные. Первый — index.html , который будет содержать некоторый базовый HTML, а другой — index.js , который будет ссылаться на все наши другие файлы JavaScript, а также на наши файлы SCSS:

 cd .. touch index.html index.js 

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

Немного базового HTML

Начнем с добавления некоторого базового HTML-кода в файл index.html . Hyperapp заботится о создании HTML и может отображать его непосредственно в <body> . Это означает, что нам нужно только установить метаинформацию, содержащуюся в <head> . За исключением значения тега <title> , вы можете использовать один и тот же файл index.html для каждого проекта. Откройте index.html в вашем любимом текстовом редакторе и добавьте следующий код:

 <!doctype html> <html lang='en'> <head> <meta charset='utf-8'> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>HyperList</title> </head> <body> <script src='index.js'></script> </body> </html> 

Теперь пришло время добавить код JavaScript!

ES6 Модули

Собственные модули JavaScript были введены в ES6 (он же ES2015). К сожалению, браузеры не спешат перенимать использование модулей ES6 изначально, хотя сейчас все начинает улучшаться . К счастью, мы все еще можем использовать их для организации нашего кода, и Parcel разберется во всех их частях.

Начнем с добавления кода для начального состояния в файл state.js :

 const state = { items: [], input: '', placeholder: 'Make a list..' }; export default state; 

Это то же самое, что и объект, который мы использовали в предыдущей статье , но с объявлением export в конце. Это сделает объект доступным для любого другого файла, который его импортирует. Делая это экспортом по умолчанию, нам не нужно явно указывать его имя, когда мы импортируем его позже.

Далее мы добавим действия в actions.js :

 const actions = { add: () => state => ({ input: '', items: state.items.concat({ value: state.input, completed: false, id: Date.now() }) }), input: ({ value }) => ({ input: value }), toggle: id => state => ({ items: state.items.map(item => ( id === item.id ? Object.assign({}, item, { completed: !item.completed }) : item )) }), destroy: id => state => ({ items: state.items.filter(item => item.id !== id) }), clearAllCompleted: ({ items }) => ({ items: items.filter(item => !item.completed) }) }; export default actions; 

Опять же, это то же самое, что и объект, который мы использовали в предыдущей статье, с добавлением объявления export в конце.

И наконец, мы добавим код представления в view.js :

 import { h } from 'hyperapp' const AddItem = ({ add, input, value, placeholder }) => ( <div class='flex'> <input type="text" onkeyup={e => (e.keyCode === 13 ? add() : null)} oninput={e => input({ value: e.target.value })} value={value} placeholder={placeholder} /> <button onclick={add}></button> </div> ); const ListItem = ({ value, id, completed, toggle, destroy }) => ( <li class={completed && "completed"} id={id} key={id} onclick={e => toggle(id)}> {value} <button onclick={ () => destroy(id) }>x</button> </li> ); const view = (state, actions) => ( <div> <h1><strong>Hyper</strong>List</h1> <AddItem add={actions.add} input={actions.input} value={state.input} placeholder={state.placeholder} /> <ul id='list'> {state.items.map(item => ( <ListItem id={item.id} value={item.value} completed={item.completed} toggle={actions.toggle} destroy={actions.destroy} /> ))} </ul> <button onclick={() => actions.clearAllCompleted({ items: state.items }) }> Clear completed items </button> </div>s ); export default view; 

Прежде всего, этот файл использует объявление import для импорта модуля h из библиотеки Hyperapp, которую мы установили ранее с помощью npm. Это функция, которую Hyperapp использует для создания узлов Virtual DOM, которые составляют представление.

Этот файл содержит два компонента: AddItem и ListItem . Это просто функции, которые возвращают код JSX и используются для абстрагирования различных частей представления в отдельные строительные блоки. Если вы обнаружите, что используете большое количество компонентов, возможно, стоит переместить их в отдельный файл components.js а затем импортировать их в файл view.js

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

Теперь мы добавили весь наш код JavaScript, нам просто нужно собрать его все вместе в файле index.js . Это делается с помощью директивы import . Добавьте следующий код в index.js :

 import { app } from 'hyperapp' import state from './js/state.js' import actions from './js/actions.js' import view from './js/view.js' const main = app(state, actions, view, document.body); 

Это импортирует функцию app из библиотеки Hyperapp, а затем импортирует три файла JavaScript, которые мы только что создали. Объект или функция, которые были экспортированы из каждого из этих файлов, присваиваются переменным state , actions и view соответственно, поэтому на них можно ссылаться в этом файле.

Последняя строка кода вызывает функцию app , которая запускает приложение. Он использует каждую из переменных, созданных из наших импортированных файлов, в качестве первых трех аргументов. Последний аргумент — это HTML-элемент, в котором будет отображаться приложение — по соглашению, это document.body .

Добавить стиль

Прежде чем приступить к созданию нашего приложения, мы должны придать ему стиль. Давайте перейдем в каталог src и создадим папку для нашего SCSS:

 mkdir src/scss 

Теперь мы создадим два файла, которые будут содержать код SCSS, который мы использовали в первой части:

 cd src/scss touch index.scss _settings.scss 

Мы используем файл с именем _settings.scss для хранения всех переменных Sass для различных шрифтов и цветов, которые будет использовать наше приложение. Это облегчает их поиск, если вы решите обновить любое из этих значений в будущем. Откройте файл _settings.scss и добавьте следующий код:

 // fonts @import url("https://fonts.googleapis.com/css?family=Racing+Sans+One"); $base-fonts: Helvetica Neue, sans-serif; $heading-font: Racing Sans One, sans-serif; // colors $primary-color: #00caff; $secondary-color: hotpink; $bg-color: #222; 

Специфичный для приложения CSS находится в index.scss , но нам нужно убедиться, что мы импортируем файл _settings.scss в начале, так как переменные, которые в нем содержатся, упоминаются позже в файле. Откройте index.scss и добавьте следующий код:

 @import 'settings'; * { margin: 0; padding: 0; box-sizing: border-box; } body { padding-top: 50px; background: $bg-color; color: $primary-color; display: flex; height: 100vh; justify-content: center; font-family: $base-fonts; } h1 { color: $secondary-color; & strong{ color: $primary-color; } font-family: $heading-font; font-weight: 100; font-size: 4.2em; text-align: center; } a{ color: $primary-color; } .flex{ display: flex; align-items: top; margin: 20px 0; input { border: 1px solid $primary-color; background-color: $primary-color; font-size: 1.5em; font-weight: 200; width: 50vw; height: 62px; padding: 15px 20px; margin: 0; outline: 0; &::-webkit-input-placeholder { color: $bg-color; } &::-moz-placeholder { color: $bg-color; } &::-ms-input-placeholder { color: $bg-color; } &:hover, &:focus, &:active { background: $primary-color; } } button { height: 62px; font-size: 1.8em; padding: 5px 15px; margin: 0 3px; } } ul#list { display: flex; flex-direction: column; padding: 0; margin: 1.2em; width: 50vw; li { font-size: 1.8em; vertical-align: bottom; &.completed{ color: $secondary-color; text-decoration: line-through; button{ color: $primary-color; } } button { background: none; border: none; color: $secondary-color; outline: none; font-size: 0.8em; font-weight: 50; padding-top: 0.3em; margin-left: 5px; } } } button { background: $bg-color; border-radius: 0px; border: 1px solid $primary-color; color: $primary-color; font-weight: 100; outline: none; padding: 5px; margin: 0; &:hover, &:disabled { background: $primary-color; color: #111; } &:active { outline: 2px solid $primary-color; } &:focus { border: 1px solid $primary-color; } } 

Если ваш SCSS начинает усложняться, вы можете разбить его на отдельные файлы и затем импортировать их все в index.scss .

Теперь нам нужно связать эти файлы с нашим приложением. На самом деле мы не размещаем ссылку в нашем HTML-файле, как вы это обычно делаете с CSS. Вместо этого мы index.js его в файл index.js . Это потому, что мы используем SCSS, и его нужно предварительно обработать в CSS. Parcel сделает это за нас, а также разберется, связывая HTML-файл со стандартным CSS-файлом, который он создает.

Чтобы импортировать файлы SCSS, нам просто нужно обновить наш файл index.js в него следующую строку:

 import './scss/index.scss' 

Теперь, когда весь наш код завершен, пришло время начать работу над процессом сборки!

галдеж

Babel преобразует современный код JavaScript в код, который может использовать большинство браузеров. Он также позаботится о переписывании кода JSX в чистый JavaScript.

Чтобы использовать Babel с преобразованиями JSX, нам нужно установить его вместе с плагином JSX:

 npm install --save babel-plugin-transform-react-jsx babel-preset-env 

Нам также нужно создать файл .babel.rc который будет .babel.rc Babel использовать функцию h из Hyperapp при обработке JSX. Следующий код создаст файл с соответствующей информацией:

 echo '{ "plugins": [["transform-react-jsx", { "pragma": "h" }]] }' > .babelrc 

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

Посылка

К сожалению, наш код в настоящее время не работает во всех браузерах. Нам нужно использовать процесс сборки для переноса нашего кода ES6 + в ES5 и объединения всех наших файлов JS в один файл. Давайте использовать Parcel, чтобы сделать это.

Parcel — это пакет модулей, похожий на webpack или Rollup, который обещает нулевую конфигурацию и невероятно быстр. Это позволяет нам писать современный JavaScript в отдельных файлах, а затем объединять их в один минимизированный файл JavaScript, который сможет использовать большинство браузеров. Он также поддерживает несколько файлов CSS, SCSS и PostCSS из коробки.

Прежде всего, давайте установим Parcel:

 npm install --save parcel-bundler 

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

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

 ./node_modules/.bin/parcel src/index.html --out-dir docs 

Это указывает, что точкой входа является файл index.html . Это все, что нужно знать Parcel, поскольку он перейдет по ссылке на index.js которая находится в этом файле, а затем будет следовать директивам import в этом файле.

Он также указывает, что папка с именем docs будет использоваться для вывода всех статических файлов в. По умолчанию это обычно называется dist — но, как вы увидите позже, нам нужно, чтобы он назывался docs чтобы мы могли интегрировать его с GitHub Pages.

Вы также должны увидеть сообщение о том, что приложение создается в окне терминала. Вы можете даже заметить, что Parcel устанавливает для вас модуль npm node-sass , поскольку он автоматически замечает, что мы используем файлы SCSS, но также и что у нас не установлен node-sass . Как это круто?!

Через несколько секунд вы должны увидеть сообщение, подобное следующему:

 Server running at http://localhost:1234  Built in 3.15s. 

Сервер теперь запущен, и если вы откроете браузер и перейдете по адресу http: // localhost: 1234 , вы увидите, что приложение запущено. Это будет обновляться на лету, поэтому любые изменения, внесенные вами в код, будут отражены на странице сразу (или после небольшой паузы для перестройки кода). Он также загружает модули, поэтому он автоматически установит все модули npm, которые требуются, когда они необходимы, как это было сделано с «node-sass». Потрясающие!

Как только вы будете довольны тем, как выглядит сайт, самое время создать статический сайт. Прежде всего, остановите работу сервера, удерживая Ctrl и c вместе. Затем выполните в терминале следующую команду:

 ./node_modules/.bin/parcel build src/index.html --out-dir docs --public-url ./ 

Это создаст статические файлы и поместит их в папку с docs .

Если вы берете пик в папке с docs , вы должны найти файл с именем index.html . Откройте его в браузере, и вы увидите, что сайт работает, используя только статические файлы в папке docs . Parcel объединил весь соответствующий код и использовал Babel для переноса нашего современного JavaScript в один файл JavaScript и использовал node-sass для предварительной обработки наших файлов SCSS в один файл CSS. Откройте их, и вы увидите, что код также был свернут!

Сценарии npm

В npm есть полезная функция, называемая скриптами, которая позволяет вам запускать определенные фрагменты кода с помощью одной команды. Мы можем использовать это для создания пары скриптов, которые ускорят использование Parcel.

Добавьте следующее в раздел «scripts» файла package.json :

 "start": "parcel src/index.html --out-dir docs", "build": "parcel build src/index.html --out-dir docs --public-url ./" 

Теперь мы можем просто запустить следующие команды для запуска сервера:

 npm start 

И следующая команда запустит процесс сборки:

 npm run build 

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

Развертывание на страницах GitHub

GitHub — это отличное место для размещения вашего кода, а также отличная функция GitHub Pages, которая позволяет размещать статические сайты на GitHub. Для начала вам нужно убедиться, что у вас есть учетная запись GitHub и у вас установлен git на локальном компьютере.

Чтобы убедиться, что мы не gitignore ненужные файлы, давайте добавим файл hyperlist каталог hyperlist :

 touch .gitignore 

Как следует из названия, этот файл сообщает git, какие файлы (или шаблоны) он должен игнорировать. Обычно он используется, чтобы избежать фиксации файлов, которые бесполезны для других соавторов (например, создание временных файлов IDE и т. Д.).

Я бы рекомендовал добавить следующие элементы, чтобы убедиться, что они не отслеживаются git (помните, что gitignore — это скрытый файл!):

 # Logs logs *.log npm-debug.log* # Runtime data pids *.pid *.seed # Dependency directory node_modules # Optional npm cache directory .npm # Optional REPL history .node_repl_history # Cache for Parcel .cache # Apple stuff .DS_Store 

Теперь мы готовы инициализировать git в каталоге hyperlist :

 git init 

Далее мы добавляем все файлы, которые мы создали до сих пор:

 git add . 

Затем мы передаем эти файлы для контроля версий:

 git commit -m 'Initial Commit' 

Теперь, когда наши важные файлы отслеживаются с помощью git, нам нужно создать удаленный репозиторий на GitHub. Просто войдите в свою учетную запись, нажмите кнопку « Новый репозиторий» и следуйте инструкциям. Если вы застряли, вы можете обратиться к документации GitHub здесь: Создать Репо .

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

 git remote add origin https://github.com/<username>/<repo-name>.git 

Обязательно замените <username> и <repo-name> на правильные значения. Если вы хотите убедиться, что вы все сделали правильно, вы можете использовать git remote -v .

И, наконец, нам нужно отправить наш код на GitHub:

 git push origin master 

Это подтолкнет весь ваш код в ваш репозиторий GitHub, включая статические файлы в каталоге docs . GitHub Pages теперь можно настроить для использования файлов в этом каталоге. Для этого войдите в хранилище на GitHub, перейдите в раздел « Настройки » хранилища и прокрутите вниз до раздела « Страницы GitHub ». Затем в разделе « Источник» выберите параметр «Папка master branch / docs», как показано на снимке экрана ниже:

Ваш сайт GitHub Pages в настоящее время создается из папки / docs в главной ветке. Учить больше

Это должно означать, что теперь вы можете получить доступ к приложению по следующему адресу: https://username.github.io/repo-name.

Например, вы можете посмотреть наши по адресу sitepoint-editors.github.io/hyperlist/ .

Workflow

Отныне, если вы вносите какие-либо изменения в свое приложение, вы можете придерживаться следующего рабочего процесса:

  1. запустить сервер разработки: npm start
  2. внести любые изменения
  3. проверьте, что изменения работают на сервере разработки
  4. выключите сервер, удерживая Ctrl + c
  5. перестройте приложение: npm run build
  6. внесите изменения для коммита: git add .
  7. зафиксировать все изменения в git: git commit -m 'latest update'
  8. нажмите изменения в GitHub: git push origin master .

Мы можем ускорить этот процесс, создав сценарий npm, чтобы выполнить последние три шага за один раз. Добавьте следующее к записи «scripts» в package.json :

 "deploy": "npm run build && git add . && git commit -a -m 'latest build' && git push origin master" 

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

 npm run deploy 

Вот и все, ребята!

И это подводит нас к концу этого урока. Я использовал приложение, которое мы создали в первой части этого руководства, но принципы остаются неизменными для большинства проектов JavaScript. Надеюсь, я продемонстрировал, как легко использовать Parcel для создания статического сайта JS и автоматического развертывания его на страницах GitHub с помощью одной команды!