При переходе с других сборщиков, особенно с Webpack, разработчики часто сталкиваются с ощущением, что некоторые важные возможности исчезли. На практике большинство таких функций в Parcel либо встроены по умолчанию, либо реализуются иначе.
Parcel придерживается концепции zero-configuration, поэтому многие настройки, которые раньше требовали десятков строк конфигурации, работают автоматически. Именно это и становится причиной путаницы: функция существует, но её больше не нужно явно включать.
После опыта работы с Webpack многие ожидают увидеть файл:
webpack.config.js
или аналогичную централизованную конфигурацию.
Parcel в большинстве случаев не требует отдельного конфигурационного файла.
Вместо этого используются:
package.json.parcelrc (при необходимости расширения поведения)Например:
{
"source": "src/index.html"
}
Запуск:
parcel build
Уже достаточен для полноценной сборки проекта.
.parcelrcЕсли необходимо изменить конвейер обработки ресурсов:
{
"extends": "@parcel/config-default",
"transformers": {
"*.md": ["@parcel/transformer-raw"]
}
}
Файл .parcelrc становится аналогом сложных настроек
Webpack.
В Webpack практически любой тип файла подключается через Loader:
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
Parcel использует систему Transformers.
Большинство популярных типов файлов уже поддерживаются:
Пример импорта:
import './styles.scss';
Parcel автоматически:
Никаких дополнительных правил не требуется.
Вместо Loader используется Transformer:
{
"transformers": {
"*.txt": ["@parcel/transformer-raw"]
}
}
Webpack активно использует плагины:
plugins: [
new HtmlWebpackPlugin(),
new CopyWebpackPlugin()
]
Parcel использует специализированную архитектуру:
Каждая часть отвечает только за свою задачу.
Например:
| Webpack Plugin | Parcel-аналог |
|---|---|
| HtmlWebpackPlugin | встроен |
| MiniCssExtractPlugin | встроен |
| TerserPlugin | встроен |
| CopyPlugin | встроенная обработка ресурсов |
Вместо универсального Plugin API создаются специализированные расширения:
const { Optimizer } = require('@parcel/plugin');
module.exports = new Optimizer({
async optimize({ bundle, contents }) {
return {
contents
};
}
});
В Webpack HTML-файл обычно генерируется через:
new HtmlWebpackPlugin()
HTML является полноценной точкой входа.
Файл:
<!DOCTYPE html>
<html>
<head>
<script type="module" src="./app.js"></script>
</head>
</html>
Запуск:
parcel index.html
Parcel автоматически:
Дополнительные плагины не нужны.
Копирование ресурсов:
new CopyWebpackPlugin({
patterns: [
{ from: 'public' }
]
})
Статические ресурсы могут импортироваться напрямую.
Например:
import logo from './assets/logo.png';
или использоваться в HTML:
<img src="./assets/logo.png">
Parcel самостоятельно:
Если требуется простое копирование файлов без обработки:
{
"staticFiles": {
"staticPath": "public"
}
}
или использование дополнительных пакетов для статического контента.
Конфигурация Webpack:
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
Обычный импорт:
import './style.css';
Parcel автоматически:
Никакие Loader не требуются.
{
test: /\.(png|jpg)$/i,
use: ['file-loader']
}
Любой ресурс импортируется напрямую:
import image from './photo.jpg';
После сборки:
console.log(image);
выведет путь к итоговому файлу:
/photo.83f2a1d.jpg
Встраивание небольших файлов через Data URI:
url-loader
Parcel автоматически принимает решение о встраивании ресурсов.
Для маленьких файлов возможно создание:
data:image/png;base64,...
Для больших — отдельного файла.
Ручная настройка обычно не требуется.
В Webpack:
new MiniCssExtractPlugin()
используется для выделения CSS в отдельные файлы.
Parcel делает это автоматически при production-сборке.
Команда:
parcel build src/index.html
создаст:
index.js
index.css
без дополнительной конфигурации.
Минификация Jav * aScript:
new TerserPlugin()
При production-сборке минификация выполняется автоматически:
parcel build
Parcel:
В Webpack:
{
test: /\.js$/,
loader: 'babel-loader'
}
Parcel автоматически обнаруживает конфигурацию Babel.
Например:
{
"presets": ["@babel/preset-env"]
}
Файл:
.babelrc
или:
{
"babel": {
"presets": ["@babel/preset-env"]
}
}
в package.json.
Parcel самостоятельно подключает Babel при необходимости.
В Webpack:
new DefinePlugin({
API_URL: JSON.stringify('https://api.site.com')
})
Использование переменных окружения.
Файл:
.env
API_URL=https://api.site.com
Использование:
console.log(process.env.API_URL);
или:
console.log(import.meta.env.API_URL);
в зависимости от версии и конфигурации проекта.
В Webpack:
resolve: {
alias: {
"@": "./src"
}
}
Псевдонимы настраиваются через package.json.
{
"alias": {
"@": "./src"
}
}
Использование:
import Button from '@/components/Button';
Настройки:
devServer: {
hot: true,
port: 3000
}
Сервер запускается автоматически:
parcel src/index.html
По умолчанию доступны:
Изменение порта:
parcel src/index.html --port 3000
В Webpack HMR требует отдельной настройки.
HMR встроен.
Файл:
export const version = 1;
После изменения модуль обновляется без полной перезагрузки страницы.
При необходимости можно использовать API:
if (module.hot) {
module.hot.accept();
}
Хотя в большинстве проектов даже это не требуется.
Webpack:
optimization: {
splitChunks: {
chunks: 'all'
}
}
Parcel автоматически анализирует граф зависимостей.
Если код используется несколькими точками входа:
import './shared.js';
Parcel создаст общий бандл самостоятельно.
const module = await import('./admin.js');
создаёт отдельный chunk автоматически.
В новых версиях Webpack:
type: 'asset/resource'
или
type: 'asset/inline'
Любой ресурс является частью графа зависимостей.
Пример:
import pdf from './manual.pdf';
import icon from './icon.svg';
import image from './image.png';
Parcel самостоятельно выбирает способ обработки.
В Webpack Tree Shaking часто требует специальных настроек.
Tree Shaking встроен по умолчанию.
Исходный код:
export function used() {}
export function unused() {}
Импорт:
import { used } from './utils';
В production-бандл попадёт только используемая функция.
devtool: 'source-map'
Source Maps генерируются автоматически.
Режим разработки:
parcel src/index.html
включает карты исходников по умолчанию.
Для production доступны дополнительные параметры:
parcel build --no-source-maps
| Возможность Webpack | Эквивалент в Parcel |
|---|---|
| webpack.config.js | Обычно не нужен |
| Loader | Transformer |
| Plugin | Специализированные расширения Parcel |
| HtmlWebpackPlugin | Встроенная работа с HTML |
| CopyWebpackPlugin | Автоматическая обработка ресурсов |
| file-loader | Импорт файлов |
| url-loader | Автоматическое встраивание |
| css-loader | Встроенная поддержка CSS |
| style-loader | Встроенное подключение стилей |
| MiniCssExtractPlugin | Автоматическое выделение CSS |
| TerserPlugin | Встроенная минификация |
| babel-loader | Автоматическое обнаружение Babel |
| DefinePlugin | Переменные окружения |
| alias | Поле alias в package.json |
| devServer | Встроенный сервер разработки |
| HMR | Встроенный HMR |
| SplitChunks | Автоматическое разделение кода |
| Asset Modules | Встроенная система ресурсов |
| Tree Shaking | Встроенный механизм |
| Source Maps | Генерируются автоматически |
Главная особенность Parcel заключается в том, что большинство функций, которые в других сборщиках воспринимаются как отдельные плагины, загрузчики или секции конфигурации, представлены встроенными механизмами. Поэтому при миграции многие возможности кажутся отсутствующими, хотя фактически они уже активированы и работают без дополнительной настройки.