Parcel-bundler - стоит ли использовать?

TLDR использовать стоит.

Недавно вышел новый инструмент сборки javascript проектов - https://github.com/parcel-bundler/parcel.

Возникает вопрос - брать или не брать, стоит ли пользоваться этим порождением javascript экосистемы. Я попробовал использовать его для сборки фронтенда проекта https://a.jscourse.com/ru/ и в целом рекомендую.

Когда стоит пробовать/ипользовать parcel-bundler:

  • начинающим фронтендерам. Потому что сборщик не требует (почти) настройки и батарейки включены (встроенный сервер + перезагрузка при изменении файлов проекта).
  • когда хотите альтернативу webpack-а.

Из минусов с которым я столкнулся:

  • не очевидно как контролировать имена результирующих файлов при компиляции. Невозможность положить css. и js в разные папки.
  • при программном запуске (я поднимаю сервер для разработки вместе с сервером бекенда) parcel “проглатывает” логи и не выводит их вмесе с серверными. Обошелся патчем локально установленного модуля. Навряд у тебя будет такая же проблема.
  • все же некоторая донастройка требуется. Пришлось докидывать .babelrc и ставить некоторые пакеты чтобы заработали экспериментальные декораторы.

Из плюсов:

  • отсутствие системы плагинов как в вебпаке. История обновления началась с того что я захотел обновить вебпак до новой версии, но некоторые плагины, которые я использовал не обновились до новой версии. При этом чем больше у тебя таких плагинов в проекте, тем больше шанс что кто-то из них сломается, тем самым сломает процесс сборки.
  • скорость старта быстрее чем у вебпака.
  • много, очень много что работает из коробки. Например require less файлов из js файлов. В вебпаке чтобы настроить такую механику нужно попотеть.

А какой для тебя необходимый набор требований(минимальный, желательный, максимальный) для сборки проекта ? Пользовался ли ты другими сборщиками типа Grunt, Gulp и др. и отчего они появляются все новые и новые и где найти серебряную пулю, мож запилить свою? :))

И что такое “батарейка”, чет я не въехал, если честно? :) (это того что я пользовался в оч ограниченном варианте вебпаком)

  • перезагрузка при билде
  • последний писк моей моды - интеграция с expressjs чтобы процесс сборки запускался вместе с разрабоческим сервером. Первый пункт тоже должен быть соблюден.
  • сборка смешанных ассетов - скрипты, стили, при том чтобы можно было запилить как js, jsx, так и typescript и tsx, less.
  • минификация, sourcemaps для продашен сборки.
  • визуализация результирующего собранного файла (типа сколько места какие модули заняли).
  • минимум плагинов. Задолбаешься их обновлять при обновлении версии главного сборщика.
  • минимум настройки. То же самое - задолбаешься понимать и менять при обновлении.

Максимально:

  • поддержка code split. Это когда не все файлы складываются в результируюций бандл, а некоторые лежат рядом с бандлом и подгружаются по требованию.
  • отсутствие необходимости любой настройки.
  • tree-shaking - умное выкидывание неиспользуемого кода.
  • минификация названий классов и id (вот честно не знаю как такое сделать, но хотел бы).

Пользовался grun-ом. На gulp только посмотрел и прошел мимо. Не зацепил меня парень. Вебпак был моим выбором по умолчанию до того как столкнулся с parcel и до того как попробовал обновить webpack3 до webpack4 на небольшом проекте.

Это значит что вот такую конфигурацию вебпака

const {isDevelopment} = require('./src/utils')
const npmPath = require('path')
const isDev = process.env.NODE_ENV === 'development'
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const CleanCSSPlugin = require('less-plugin-clean-css')
const webpack = require('webpack')

const extractLess = new ExtractTextPlugin({
    filename: '../css/client.min.css',
    disable: isDev
})

const plugins = [
    new webpack.optimize.CommonsChunkPlugin({
        name: 'common'
        , children: true
    }),
    extractLess,
    new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV)
        }
    }),
    new webpack.HotModuleReplacementPlugin()
]

if (!isDev) {
    plugins.push(new webpack.optimize.UglifyJsPlugin({
        sourceMap: true
    }))
}

let entry = ['./src/client']
if (isDevelopment()) {
    console.log('isDevelopment', isDevelopment())
    entry.unshift('webpack-hot-middleware/client?reload=true&quiet=true')
}

module.exports = {
    entry,
    devtool: isDev ? 'inline-source-map' : false,
    output: {
        filename: 'client.min.js',
        path: npmPath.resolve(__dirname, './static/js/'),
        publicPath: '/js/'
    },
    plugins: plugins,
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.less', '.css']
    },
    module: {
        rules: [{
            test: /\.[tj]sx?$/,
            exclude: /node_modules|static/,
            loader: 'awesome-typescript-loader'
        }, {
            test: /\.less$/,
            use: extractLess.extract({
                use: [{
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "less-loader",
                    options: {
                        plugins: [new CleanCSSPlugin({advanced: true})],
                        sourceMap: true
                    }
                }],
                fallback: "style-loader"
            })
        }, {
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    }
}

9 зависимостей, которые нужны чтобы этот код заработал (не говоря о том что мне пришлось найти способ чтобы конфигурационнный файл был .ts чтобы я мог использовать одни и те же utils на сервере и в вебпаке). Я заменил на одну зависимость parcel-bundler + станцевал чтобы он компилировал декораторы в js (понадобилось 4 плагина для babel-я и файл конфигурации бабеля).

И да, еще получил более плавную интеграцию с expressjs без единого плагина.

“Батарейки включены” - значит что этот инструмент проще взять и начать использовать.

Блин, я же скринкаст делал про минимальную сборку.

И код https://github.com/podgorniy/webpack-start

минификация названий классов и id (вот честно не знаю как такое сделать, но хотел бы).

Так а почему ты не можешь пройтись по всему коду собрать классы и ид и подменить каждый уникальный одной буквой, если в кодировки UTF-8 разных алфавитов? Или используя только латинский алфавит 0-9 a-z A-z, а когда закончатся буквы использовать две в зависимости от произведения длинны класса*кол-во классов в коде ?

Только в доме они будут выглядеть не оч красиво и главное что б Js не отвалился, но для Js можно придумать спец. метки для именования например какой то префикс или суффикс но эт гемор конечно :))

Если ты про эти ид и классы и если есть HTML CSS - отсюда вроде легко забрать JS - здесь наверно нужна доп. метка, чтоб легко было забрать.

Вот эта операция самая сложная. Часть классов описана в темлейтах на сервере, часть в клиентских темплейтах, часть вообще генерируется в js.

Именно.