Parcel — очень быстрый бандлер, не требующий настройки

в 10:57, , рубрики: bundler, javascript, Node, node.js, parcel, webpack, Разработка веб-сайтов

Parcel — очень быстрый бандлер, не требующий настройки - 1

Для чего

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;
}

Результат

Parcel — очень быстрый бандлер, не требующий настройки - 2

И это все. Как можно заметить, мы не потратили ни минуты на написание конфигурационных файлов, за исключением .babelrc и .postcssrc

Подводя некий итог

Перед нами эдакий "Webpack на минималках", предоставляющий возможность быстрого развертывания рабочего окружения для небольшого проекта. Стек технологий по сути ограничен лишь стандартным набором ассетов, но в любой момент его можно расширить и своими собственными. С учетом полной поддержки Babel мы легко можем использовать практически любой другой фреймворк или библиотеку (разве что с Angular будут сложности, ведь писать с его помощью на ES6 и без родного инструментария — задача на любителя), а поддержка PostCSS из коробки является еще одним приятным дополнением.

Из неудобств я пока что могу отметить только одно — при работе с TypeScript бандлер не учитывает пользовательские пути и базовый каталог (секции baseUrl и paths), указанные в файле tsconfig, и, соответственно, не может нормально разрешать пути импортируемых модулей. На гитхабе идет обсуждение решения этой проблемы.

Автор: xxxTy3uKxxx

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js