
Parcel — очень быстрый бандлер, не требующий настройки
Для чего
Parcel — маленький и быстрый бандлер, позиционируется как решение для маленьких проектов. С момента первого релиза (7 дней назад) уже собрал 8725 звездочек на гитхабе. Согласно официальной документации имеет следующие плюсы:
Быстрая сборка
Parcel использует worker process для многопоточной сборки, а так же имеет свой файловый кэш для быстрой пересборки при последующих изменениях.
Собирает все ваши ассеты
Из коробки имеется поддержка ES6, TypeScript, CoffeeScript, HTML, SCSS, Stylus, raw-файлов. Плагины не требуются.
Автоматические преобразования
Весь код автоматически проходит через Babel, PostCSS, PostHTML — подхватываются при необходимости из node_modules.
️ Разделение кода без лишней конфигурации
Используя динамический import(), Parcel разделяет бандл для возможности быстрой начальной загрузки точки входа в приложение
Горячая перезагрузка
Типичный хот-релоад без конфигурации — сохраняете изменения и они автоматически применяются в браузере.
Дружелюбный вывод ошибок
При ошибке подсвечивается кусок кода, в котором она произошла.
Так же на главной странице приводится бенчмарк:
Bundler | Time |
---|---|
browserify | 22.98s |
webpack | 20.71s |
parcel | 9.98s |
parcel — with cache | 2.64s |
Механика работы
Подход Parcel схож с оным у Webpack (тут сложно придумать что-то новое).
У нас есть сущность — Asset. Ассет — это любой файл. Механика работы такова: реализуется интерфейс, который предоставляет логику для превращения файла в AST, разрешения всех зависимостей, применения нужных трансформаций и генерирования итогового кода. Если вас не устраивает работа какого-то ассета из коробки или вы хотите добавить свой — нет ничего сложного.
Дальше в дело вступает Packager. Упаковщик склеивает ассеты в итоговый бандл. Это происходит после обработки и успешного построения дерева. Упаковщики регистрируются на основе типа файлов. Хотите написать свой упаковщик? Вам сюда.
Так же мы можем писать свои плагины, которые Parcel будет подхватывать из package.json. Для этого у названия пакета плагина должен быть префикс parcel-plugin-
. Но это уже совсем частный случай, который скорее всего уже ведет к тому, что надо переключаться на webpack или другой удобный инструмент.
На практике
Ставим пакет, инициализируем приложение через любой пакетный менеджер:
$ yarn global add parcel-bundler
$ mkdir parcel-test && cd parcel-test
$ yarn init -y
Для примера напишем hello world на Preact. Создадим следующую структуру:
parcel-test
├── package.json
├── src
│ ├── app.jsx
│ ├── components
│ │ └── clock
│ │ └── Clock.jsx
│ └── index.html
└── yarn.lock
3 directories, 5 files
А так же установим необходимые пакеты:
$ yarn add preact babel-plugin-transform-react-jsx postcss-modules autoprefixer
Для того, чтобы сконфигурировать Babel создадим .babelrc со следующим содержанием:
{
"plugins": [
["transform-react-jsx", { "pragma":"h" }]
]
}
Для PostCSS:
{
"modules": true,
"plugins": {
"autoprefixer": {}
}
}
Для autoprefixer:
> 1%
last 2 versions
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Parcel demo</title>
</head>
<body>
<script src="./App.jsx"></script>
</body>
</html>
App.jsx
import { h, render } from 'preact';
import { Clock } from './components/clock/Clock';
render((
<div>
<h1>It works!</h1>
<Clock />
</div>
), document.body);
Clock.jsx
import { h, Component } from 'preact';
import styles from './Clock.css';
export class Clock extends Component {
constructor() {
super();
this.state = {
time: Date.now()
};
}
componentDidMount() {
this.timer = setInterval(() => this.setState({ time: Date.now() }), 1000);
}
componentWillUnmount() {
cleanInterval(this.timer);
}
render(props, state) {
let time = new Date(state.time).toLocaleTimeString();
return <span className={styles.clock}>{ time }</span>
}
}
Clock.css
.clock {
color: green;
}
И это все. Как можно заметить, мы не потратили ни минуты на написание конфигурационных файлов, за исключением .babelrc и .postcssrc
Подводя некий итог
Перед нами эдакий "Webpack на минималках", предоставляющий возможность быстрого развертывания рабочего окружения для небольшого проекта. Стек технологий по сути ограничен лишь стандартным набором ассетов, но в любой момент его можно расширить и своими собственными. С учетом полной поддержки Babel мы легко можем использовать практически любой другой фреймворк или библиотеку (разве что с Angular будут сложности, ведь писать с его помощью на ES6 и без родного инструментария — задача на любителя), а поддержка PostCSS из коробки является еще одним приятным дополнением.
Из неудобств я пока что могу отметить только одно — при работе с TypeScript бандлер не учитывает пользовательские пути и базовый каталог (секции baseUrl
и paths
), указанные в файле tsconfig, и, соответственно, не может нормально разрешать пути импортируемых модулей. На гитхабе идет обсуждение решения этой проблемы.
Comments 68
Only users with full accounts can post comments. Log in, please.