[Разработка веб-сайтов, JavaScript, Программирование] Изучаем Parcel — альтернативу Webpack для небольших проектов
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Доброго времени суток, друзья!
Основное назначение сборщиков модулей или бандлеров, таких как Webpack или Parcel, состоит в том, чтобы обеспечить включение всех модулей, необходимых для работы приложения, в правильном порядке в один минифицированный (если речь идет о сборке для продакшна) скрипт, который подключается в index.html.
На самом деле сборщики, как правило, умеют оптимизировать не только JS, но и HTML, CSS-файлы, могут преобразовывать Less, Sass в CSS, TypeScript, React и Vue (JSX) в JavaScript, работать с изображениями, аудио, видео и другими форматами данных, а также предоставляют дополнительные возможности, такие как: создание карты (используемых) ресурсов или источников (source map), визуальное представление размера всего бандла и его отдельных частей (модулей, библиотек), разделение кода на части (chunks), в том числе, в целях переиспользования (например, библиотеки, которые используются в нескольких модулях, выносятся в отдельный файл и загружаются лишь раз), умная загрузка пакетов из npm (например, загрузка только русской локализации из moment.js), всевозможные плагины для решения специфичных задач и т.п.
В этом отношении лидерство, безусловно, принадлежит Вебпаку. Однако, что если мы разрабатываем проект, в котором большая часть функционала, предоставляемого этим замечательным инструментом, не нужна? Существуют ли альтернативы данной технологии, более простые в освоении и использовании? Для меня ответом на этот вопрос стал Parcel. К слову, если вы заинтересованы в изучении Вебпака, рекомендую к просмотру это видео. Мой файл с настройками Вебпака по данному туториалу находится здесь.
С вашего позволения, я не буду пересказывать документацию своими словами, тем паче, что она доступна на русском языке, а сосредоточусь на практической составляющей, а именно: мы с помощью шаблонных строк и динамического импорта создадим SPA, состоящее из трех страниц, на JavaScript, стилизуем приложение с помощью CSS, напишем простую функцию на TypeScript, импортируем ее в приложение, стилизуем контейнер для результатов данной функции с помощью Sass, и соберем приложение посредством Parcel в обоих режимах (разработка и продакшн).
Код проекта находится здесь.
Если вам это интересно, прошу следовать за мной.
Приложение
Готовы? Тогда поехали.
Создаем директорию parcel-tutorial.
Заходим в нее и инициализируем проект с помощью npm init -y.
Создаем файл index.html. Мы будем использовать один из стандартных шаблонов Bootstrap — Cover:
<head>
...
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
</head>
<!-- Bootstrap class -->
<body class="text-center">
<! -- Main script -->
<script src="index.js"></script>
</body>
Заходим на официальный сайт Bootstrap, переходим в раздел Examples, находим Cover в Custom components, нажимаем Ctrl+U (Cmd+U) для просмотра кода страницы.
Создаем директорию src, а в ней еще две папки — js и css.
В директории js создаем следующие файлы: header.js, footer.js, home.js, projects.js и contact.js. Это модули или, если угодно, компоненты нашего приложения: шапка, подвал, содержимое главной и других страниц.
В директории css создаем файл style.css.
На данный момент структура проекта выглядит следующим образом:
-- parcel-tutorial
-- src
-- css
-- style.css
-- js
-- contact.js
-- footer.js
-- header.js
-- home.js
-- projects.js
-- index.html
-- index.js
-- package.json
Возвращаемся к Bootstrap.
Копипастим код страницы в сооветствующие модули с небольшими изменениями.
header.js:
export default `
<header class="masthead mb-auto">
<div class="inner">
<h3 class="masthead-brand">Parcel Tutorial</h3>
<nav class="nav nav-masthead justify-content-center">
<a class="nav-link active" name="home">Home</a>
<a class="nav-link" name="projects">Projects</a>
<a class="nav-link" name="contact">Contact</a>
</nav>
</div>
</header>
`.trim()
Обратите внимание, что в ссылках мы поменяли href на name.
footer.js:
export default `
<footer class="mastfoot mt-auto">
<div class="inner">
<p>© 2020. All rights reserved.</p>
</div>
</footer>
`.trim()
home.js:
export default `
<h1 class="cover-heading">Home page</h1>
<p class="lead">Home page content</p>
`.trim()
projects.js:
export default `
<h1 class="cover-heading">Projects page</h1>
<p class="lead">Projects page content</p>
`.trim()
contact.js:
export default `
<h1 class="cover-heading">Contact page</h1>
<p class="lead">Contact page content</p>
`.trim()
Не забываем скопировать стили из cover.css в style.css.
Открываем index.js.
Импортируем шапку, подвал сайта и стили:
import header from './src/js/header.js'
import footer from './src/js/footer.js'
import './src/css/style.css'
Содержимое главной и других страниц будет загружаться динамически при клике по ссылке, поэтому создаем такой объект:
const pages = {
home: import('./src/js/home.js'),
projects: import('./src/js/projects.js'),
contact: import('./src/js/contact.js')
}
Название свойства данного объекта — соответствующая (запрашиваемая пользователем) страница.
Генерируем начальную страницу, используя импортированные ранее компоненты шапки и подвала сайта:
// Bootstrap classes
document.body.innerHTML = `
<div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
${header}
<main role="main" class="inner cover"></main>
${footer}
</div>
`.trim()
Содержимое страниц будет выводиться в элемент main, поэтому определяем его:
const mainEl = document.querySelector('main')
Создаем функцию рендеринга страниц:
const renderPage = async name => {
const template = await pages[name]
mainEl.innerHTML = template.default
}
Нам нужно дождаться загрузки соответствующего модуля, поэтому мы используем async/await (ключевое слово await приостанавливает выполнение функции). Функция принимает название запрашиваемой страницы (name) и использует его для доступа к соответствующему свойству объекта pages (pages[name]). Затем мы вставляем полученный шаблон в mainEl. В действительности, await возвращает объект Module, внутри которого содержится шаблон. Поэтому при вставке шаблона в качестве разметки в mainEl неоходимо обратиться к свойству default объекта Module (модули экспортируются по умолчанию), в противном случае, мы получим ошибку — невозможно конвертировать объект в HTML.
Рендерим главную страницу:
renderPage('home')
Активная ссылка, соответствующая текущей странице, имеет класс active. Нам нужно переключать классы при рендеринге новой страницы. Реализуем вспомогательную функцию:
const toggleClass = (activeLink, currentLink) => {
if (activeLink === currentLink) {
return;
} else {
activeLink.classList.remove('active')
currentLink.classList.add('active')
}
}
Функция принимает два аргумента — ссылку с классом active (activeLink) и ссылку, по которой кликнули (currentLink). Если указанные ссылки совпадают, ничего не делаем. Иначе, меняем классы.
Наконец, нам нужно добавить обработчик клика по ссылке. Реализуем еще одну вспомогательную функцию:
const initClickHandlers = () => {
const navEl = document.querySelector('nav')
navEl.addEventListener('click', ev => {
if (ev.target.tagName === 'A') {
const activeLink = navEl.querySelector('.active')
const currentLink = ev.target
toggleClass(activeLink, currentLink)
renderPage(currentLink.name)
}
})
}
В данной функции мы сначала находим элемент nav. Затем через делегирование обрабатываем клики по ссылкам: если целевым элементом является тег A, получаем активную ссылку (ссылку с классом active), текущую ссылку (ссылку, по которой кликнули), меняем классы и рендерим страницу. В качестве аргумента renderPage передается значение атрибута name текущей ссылки.
Мы почти закончили с приложением. Однако, прежде чем переходить к сборке проекта с помощью Parcel, необходимо отметить следующее: на сегодняшний день поддержка динамических модулей по данным Can I use составляет 90%. Это много, но мы не готовы терять 10% пользователей. Поэтому наш код нуждается в преобразовании в менее современный синтаксис. Для транспиляции используется Babel. Нам нужно подключить два дополнительных модуля:
import "core-js/stable";
import "regenerator-runtime/runtime";
Обратите внимание, что мы не устанавливаем эти модули с помощью npm.
Также давайте сразу реализуем функцию на TypeScript, что-нибудь очень простое, например, функцию сложения двух чисел.
Создаем в директории js файл index.ts следующего содержания:
export const sum = (a: number, b: number): number => a + b
Единственное отличие от JavaScript, кроме расширения файла (.ts), заключается в том, что мы явно указываем типы принимаемых и возвращаемого функцией значений — в данном случае, number (число). На самом деле, мы могли бы ограничиться определением типа возвращаемого значения, TypeScript достаточно умный для того, чтобы понять: если возвращаемое значение является числом, то и передаваемые аргументы должны быть числами. Неважно.
Импортируем эту функцию в index.js:
import { sum } from './src/js/index.ts'
И вызываем ее с аргументами 1 и 2 в renderPage:
const renderPage = async name => {
// ...
mainEl.insertAdjacentHTML('beforeend', `
<output>Result of 1 + 2 -> <span>${sum(1, 2)}<span></output>
`)
}
Стилизуем контейнер с результатом функции с помощью Sass. В папке css создаем файл style.scss следующего содержания:
$color: #8e8e8e;
output {
color: $color;
border: 1px solid $color;
border-radius: 4px;
padding: .5rem;
user-select: none;
transition: transform .2s;
& span {
color: #eee;
}
&:hover {
transform: scale(1.1);
}
}
Импортируем данные стили в index.js:
import './src/css/style.scss'
Снова обратите внимание, что мы не устанавливаем TypeScript и Sass с помощью npm.
С приложением закончили. Переходим к Parcel.
Parcel
Для глобальной установки Parcel необходимо выполнить команду npm i parcel-bundler -g в терминале.
Открываем package.json и настраиваем запуск Парсела в режимах разработки и продакшна:
"scripts": {
"dev": "parcel index.html --no-source-maps --open",
"pro": "parcel build index.html --no-source-maps --no-cache"
},
Команда npm run dev запускает сборку проекта для разработки, а команда npm run pro — для продакшна. Но что означают все эти флаги? И почему мы не устанавливали Babel, TypeScript и Sass через npm?
Дело в том, что Парсел автоматически устанавливает все зависимости при обнаружении их импорта или использования в приложении. Например, если Парсел видит импорт стилей из файла с расширением .scss, он устанавливает Sass.
Теперь о командах и флагах.
Для сборки проекта в режиме разработки используется команда parcel index.html, где index.html — это входная точка приложения, т.е. файл, в котором имеется ссылка на основной скрипт или скрипты. Также данная команда запускает локальный сервер на localhost:1234.
Флаг --no-source-maps означает, что нам не нужны карты ресурсов.
Флаг --open указывает Парселу открыть index.html после сборки в браузере на локальном сервере.
Для сборки проекта в режиме продакшна используется команда parcel build index.html. Такая сборка предполагает минификацию JS, CSS и HTML-файлов.
Флаг --no-cache означает отключение кэширования ресурсов. Кэширование обеспечивает высокую скорость сборки и пересборки проекта в режиме реального времени. Это актуально при разработке, но не актуально при сборке готового продукта. Кроме того, это усложняет задачу создания офлайн-приложения с помощью сервис-воркера.
Еще один момент: сгенерированные файлы Парсел по умолчанию помещает в папку dist, которая создается при отсутствии. Проблема в том, что при повторной сборке старые файлы не удаляются. Для удаления таких файлов нужен специальный плагин, например, parcel-plugin-clean-easy.
Устанавливаем данный плагин с помощью npm i parcel-plugin-clean-easy -D и добавляем в package.json следующее:
"parcelCleanPaths": [
"dist",
".cache"
]
parcelCleanPaths — это директории, подлежащие удалению при повторной сборке.
Теперь Парсел полностью настроен. Открываем терминал, набираем npm run dev, нажимаем enter.
Парсел собирает проект в режиме разработки, запускает локальный сервер и открывает приложение в браузере. Отлично.
Теперь попробуем собрать проект для продакшна.
Выполняем команду npm run pro.
Запускаем приложение в браузере.
Упс, кажется, что-то пошло не так.
Заглянем в сгенерированный index.html. Что мы там видим? Подсказка: обратите внимание на пути в тегах link и script. Не знаю точно, с чем это связано, но Парсел приводит относительные ссылки к виду "/path-to-file", а браузер не читает такие ссылки.
Для того, чтобы решить эту проблему, необходимо добавить в скрипт «pro» флаг "--public-url .".
Запускаем повторную сборку.
Относительные пути имеют правильный вид и приложение работает. Круто.
На этом у меня все. Благодарю за внимание.
===========
Источник:
habr.com
===========
Похожие новости:
- [Qt, Программирование микроконтроллеров] Обзор возможностей Qt Creator 4.13 и QBS 1.17 для программирования микроконтроллеров
- [Разработка веб-сайтов, Программирование, Java] Пишем чат с использованием Spring Boot и WebSockets (перевод)
- [Поисковая оптимизация, Разработка веб-сайтов] Ленивая загрузка для карт
- [Ненормальное программирование, Программирование, Совершенный код, C++] Совершенный цикл
- [JavaScript, Angular, TypeScript] Что можно положить в механизм Dependency Injection в Angular?
- [DevOps, Информационная безопасность, Разработка веб-сайтов, Разработка мобильных приложений] DevSecOps: принципы работы и сравнение SCA. Часть первая
- [Программирование микроконтроллеров, Промышленное программирование] Ethercat для начинающих
- [Информационная безопасность, IT-инфраструктура, Сетевые технологии, Сетевое оборудование] Туннель под безопасностью и брокеры сетевых пакетов
- [JavaScript] Решение частых алгоритмических вопросов на JavaScript
- [Разработка веб-сайтов, Разработка мобильных приложений, Разработка под Android, Карьера в IT-индустрии, Разработка под Windows] Нужен ли еще один сервис (opensource)? (в конце опрос)
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (Программирование), #_javascript, #_webpack, #_parcel, #_bundler, #_bundle, #_sborschik (сборщик), #_bandler (бандлер), #_bandl (бандл), #_modul (модуль), #_paket (пакет), #_biblioteka (библиотека), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_javascript, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Доброго времени суток, друзья! Основное назначение сборщиков модулей или бандлеров, таких как Webpack или Parcel, состоит в том, чтобы обеспечить включение всех модулей, необходимых для работы приложения, в правильном порядке в один минифицированный (если речь идет о сборке для продакшна) скрипт, который подключается в index.html. На самом деле сборщики, как правило, умеют оптимизировать не только JS, но и HTML, CSS-файлы, могут преобразовывать Less, Sass в CSS, TypeScript, React и Vue (JSX) в JavaScript, работать с изображениями, аудио, видео и другими форматами данных, а также предоставляют дополнительные возможности, такие как: создание карты (используемых) ресурсов или источников (source map), визуальное представление размера всего бандла и его отдельных частей (модулей, библиотек), разделение кода на части (chunks), в том числе, в целях переиспользования (например, библиотеки, которые используются в нескольких модулях, выносятся в отдельный файл и загружаются лишь раз), умная загрузка пакетов из npm (например, загрузка только русской локализации из moment.js), всевозможные плагины для решения специфичных задач и т.п. В этом отношении лидерство, безусловно, принадлежит Вебпаку. Однако, что если мы разрабатываем проект, в котором большая часть функционала, предоставляемого этим замечательным инструментом, не нужна? Существуют ли альтернативы данной технологии, более простые в освоении и использовании? Для меня ответом на этот вопрос стал Parcel. К слову, если вы заинтересованы в изучении Вебпака, рекомендую к просмотру это видео. Мой файл с настройками Вебпака по данному туториалу находится здесь. С вашего позволения, я не буду пересказывать документацию своими словами, тем паче, что она доступна на русском языке, а сосредоточусь на практической составляющей, а именно: мы с помощью шаблонных строк и динамического импорта создадим SPA, состоящее из трех страниц, на JavaScript, стилизуем приложение с помощью CSS, напишем простую функцию на TypeScript, импортируем ее в приложение, стилизуем контейнер для результатов данной функции с помощью Sass, и соберем приложение посредством Parcel в обоих режимах (разработка и продакшн). Код проекта находится здесь. Если вам это интересно, прошу следовать за мной. Приложение Готовы? Тогда поехали. Создаем директорию parcel-tutorial. Заходим в нее и инициализируем проект с помощью npm init -y. Создаем файл index.html. Мы будем использовать один из стандартных шаблонов Bootstrap — Cover: <head>
... <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> </head> <!-- Bootstrap class --> <body class="text-center"> <! -- Main script --> <script src="index.js"></script> </body> Заходим на официальный сайт Bootstrap, переходим в раздел Examples, находим Cover в Custom components, нажимаем Ctrl+U (Cmd+U) для просмотра кода страницы. Создаем директорию src, а в ней еще две папки — js и css. В директории js создаем следующие файлы: header.js, footer.js, home.js, projects.js и contact.js. Это модули или, если угодно, компоненты нашего приложения: шапка, подвал, содержимое главной и других страниц. В директории css создаем файл style.css. На данный момент структура проекта выглядит следующим образом: -- parcel-tutorial
-- src -- css -- style.css -- js -- contact.js -- footer.js -- header.js -- home.js -- projects.js -- index.html -- index.js -- package.json Возвращаемся к Bootstrap. Копипастим код страницы в сооветствующие модули с небольшими изменениями. header.js: export default `
<header class="masthead mb-auto"> <div class="inner"> <h3 class="masthead-brand">Parcel Tutorial</h3> <nav class="nav nav-masthead justify-content-center"> <a class="nav-link active" name="home">Home</a> <a class="nav-link" name="projects">Projects</a> <a class="nav-link" name="contact">Contact</a> </nav> </div> </header> `.trim() Обратите внимание, что в ссылках мы поменяли href на name. footer.js: export default `
<footer class="mastfoot mt-auto"> <div class="inner"> <p>© 2020. All rights reserved.</p> </div> </footer> `.trim() home.js: export default `
<h1 class="cover-heading">Home page</h1> <p class="lead">Home page content</p> `.trim() projects.js: export default `
<h1 class="cover-heading">Projects page</h1> <p class="lead">Projects page content</p> `.trim() contact.js: export default `
<h1 class="cover-heading">Contact page</h1> <p class="lead">Contact page content</p> `.trim() Не забываем скопировать стили из cover.css в style.css. Открываем index.js. Импортируем шапку, подвал сайта и стили: import header from './src/js/header.js'
import footer from './src/js/footer.js' import './src/css/style.css' Содержимое главной и других страниц будет загружаться динамически при клике по ссылке, поэтому создаем такой объект: const pages = {
home: import('./src/js/home.js'), projects: import('./src/js/projects.js'), contact: import('./src/js/contact.js') } Название свойства данного объекта — соответствующая (запрашиваемая пользователем) страница. Генерируем начальную страницу, используя импортированные ранее компоненты шапки и подвала сайта: // Bootstrap classes
document.body.innerHTML = ` <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column"> ${header} <main role="main" class="inner cover"></main> ${footer} </div> `.trim() Содержимое страниц будет выводиться в элемент main, поэтому определяем его: const mainEl = document.querySelector('main')
Создаем функцию рендеринга страниц: const renderPage = async name => {
const template = await pages[name] mainEl.innerHTML = template.default } Нам нужно дождаться загрузки соответствующего модуля, поэтому мы используем async/await (ключевое слово await приостанавливает выполнение функции). Функция принимает название запрашиваемой страницы (name) и использует его для доступа к соответствующему свойству объекта pages (pages[name]). Затем мы вставляем полученный шаблон в mainEl. В действительности, await возвращает объект Module, внутри которого содержится шаблон. Поэтому при вставке шаблона в качестве разметки в mainEl неоходимо обратиться к свойству default объекта Module (модули экспортируются по умолчанию), в противном случае, мы получим ошибку — невозможно конвертировать объект в HTML. Рендерим главную страницу: renderPage('home')
Активная ссылка, соответствующая текущей странице, имеет класс active. Нам нужно переключать классы при рендеринге новой страницы. Реализуем вспомогательную функцию: const toggleClass = (activeLink, currentLink) => {
if (activeLink === currentLink) { return; } else { activeLink.classList.remove('active') currentLink.classList.add('active') } } Функция принимает два аргумента — ссылку с классом active (activeLink) и ссылку, по которой кликнули (currentLink). Если указанные ссылки совпадают, ничего не делаем. Иначе, меняем классы. Наконец, нам нужно добавить обработчик клика по ссылке. Реализуем еще одну вспомогательную функцию: const initClickHandlers = () => {
const navEl = document.querySelector('nav') navEl.addEventListener('click', ev => { if (ev.target.tagName === 'A') { const activeLink = navEl.querySelector('.active') const currentLink = ev.target toggleClass(activeLink, currentLink) renderPage(currentLink.name) } }) } В данной функции мы сначала находим элемент nav. Затем через делегирование обрабатываем клики по ссылкам: если целевым элементом является тег A, получаем активную ссылку (ссылку с классом active), текущую ссылку (ссылку, по которой кликнули), меняем классы и рендерим страницу. В качестве аргумента renderPage передается значение атрибута name текущей ссылки. Мы почти закончили с приложением. Однако, прежде чем переходить к сборке проекта с помощью Parcel, необходимо отметить следующее: на сегодняшний день поддержка динамических модулей по данным Can I use составляет 90%. Это много, но мы не готовы терять 10% пользователей. Поэтому наш код нуждается в преобразовании в менее современный синтаксис. Для транспиляции используется Babel. Нам нужно подключить два дополнительных модуля: import "core-js/stable";
import "regenerator-runtime/runtime"; Обратите внимание, что мы не устанавливаем эти модули с помощью npm. Также давайте сразу реализуем функцию на TypeScript, что-нибудь очень простое, например, функцию сложения двух чисел. Создаем в директории js файл index.ts следующего содержания: export const sum = (a: number, b: number): number => a + b
Единственное отличие от JavaScript, кроме расширения файла (.ts), заключается в том, что мы явно указываем типы принимаемых и возвращаемого функцией значений — в данном случае, number (число). На самом деле, мы могли бы ограничиться определением типа возвращаемого значения, TypeScript достаточно умный для того, чтобы понять: если возвращаемое значение является числом, то и передаваемые аргументы должны быть числами. Неважно. Импортируем эту функцию в index.js: import { sum } from './src/js/index.ts'
И вызываем ее с аргументами 1 и 2 в renderPage: const renderPage = async name => {
// ... mainEl.insertAdjacentHTML('beforeend', ` <output>Result of 1 + 2 -> <span>${sum(1, 2)}<span></output> `) } Стилизуем контейнер с результатом функции с помощью Sass. В папке css создаем файл style.scss следующего содержания: $color: #8e8e8e;
output { color: $color; border: 1px solid $color; border-radius: 4px; padding: .5rem; user-select: none; transition: transform .2s; & span { color: #eee; } &:hover { transform: scale(1.1); } } Импортируем данные стили в index.js: import './src/css/style.scss'
Снова обратите внимание, что мы не устанавливаем TypeScript и Sass с помощью npm. С приложением закончили. Переходим к Parcel. Parcel Для глобальной установки Parcel необходимо выполнить команду npm i parcel-bundler -g в терминале. Открываем package.json и настраиваем запуск Парсела в режимах разработки и продакшна: "scripts": {
"dev": "parcel index.html --no-source-maps --open", "pro": "parcel build index.html --no-source-maps --no-cache" }, Команда npm run dev запускает сборку проекта для разработки, а команда npm run pro — для продакшна. Но что означают все эти флаги? И почему мы не устанавливали Babel, TypeScript и Sass через npm? Дело в том, что Парсел автоматически устанавливает все зависимости при обнаружении их импорта или использования в приложении. Например, если Парсел видит импорт стилей из файла с расширением .scss, он устанавливает Sass. Теперь о командах и флагах. Для сборки проекта в режиме разработки используется команда parcel index.html, где index.html — это входная точка приложения, т.е. файл, в котором имеется ссылка на основной скрипт или скрипты. Также данная команда запускает локальный сервер на localhost:1234. Флаг --no-source-maps означает, что нам не нужны карты ресурсов. Флаг --open указывает Парселу открыть index.html после сборки в браузере на локальном сервере. Для сборки проекта в режиме продакшна используется команда parcel build index.html. Такая сборка предполагает минификацию JS, CSS и HTML-файлов. Флаг --no-cache означает отключение кэширования ресурсов. Кэширование обеспечивает высокую скорость сборки и пересборки проекта в режиме реального времени. Это актуально при разработке, но не актуально при сборке готового продукта. Кроме того, это усложняет задачу создания офлайн-приложения с помощью сервис-воркера. Еще один момент: сгенерированные файлы Парсел по умолчанию помещает в папку dist, которая создается при отсутствии. Проблема в том, что при повторной сборке старые файлы не удаляются. Для удаления таких файлов нужен специальный плагин, например, parcel-plugin-clean-easy. Устанавливаем данный плагин с помощью npm i parcel-plugin-clean-easy -D и добавляем в package.json следующее: "parcelCleanPaths": [
"dist", ".cache" ] parcelCleanPaths — это директории, подлежащие удалению при повторной сборке. Теперь Парсел полностью настроен. Открываем терминал, набираем npm run dev, нажимаем enter. Парсел собирает проект в режиме разработки, запускает локальный сервер и открывает приложение в браузере. Отлично. Теперь попробуем собрать проект для продакшна. Выполняем команду npm run pro. Запускаем приложение в браузере. Упс, кажется, что-то пошло не так. Заглянем в сгенерированный index.html. Что мы там видим? Подсказка: обратите внимание на пути в тегах link и script. Не знаю точно, с чем это связано, но Парсел приводит относительные ссылки к виду "/path-to-file", а браузер не читает такие ссылки. Для того, чтобы решить эту проблему, необходимо добавить в скрипт «pro» флаг "--public-url .". Запускаем повторную сборку. Относительные пути имеют правильный вид и приложение работает. Круто. На этом у меня все. Благодарю за внимание. =========== Источник: habr.com =========== Похожие новости:
Разработка веб-сайтов ), #_javascript, #_programmirovanie ( Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:15
Часовой пояс: UTC + 5