Как создавать компактный и эффективный javascript используя RollupJS

rollupjs
Последнее время все чаще и чаще на ряду с другими сборщиками javascript стал встречать rollupJS. И даже стал использовать его для написания модулей, используемых в основном проекте компании. Поэтому хочу поделиться с вами переводом стать об этом компактном и удобном сборщике.

Стиль — авторский.

Узнаете, об использовании Rollup как более компактную и эффективную альтернативу webpack и Browserify для объединения файлов JavaScript.

В конце этого руководства мы сконфигурируем Rollup для:

  • объединения нашего скрипта,
  • удаления неиспользуемого кода,
  • трансплайнинг его для работы со старыми браузерами,
  • поддержки использования модулей Node в браузере,
  • работы с переменными окружения и
  • оптимизации нашего кода для уменьшения размера выходного файла

Предварительные требования


  • Начальные знания в JavaScript.
  • Первоначальное знакомство с модулями ES2015 также не повредит.
  • На вашем компьютере должен быть установлен npm. (У вас его нет? Установите Node.js здесь.)

Что такое Rollup?


Как описывают сами разработчики:
Rollup — это инструмент следующего поколение для пакетной обработки JavaScript-модулей. Создайте свое приложение или библиотеку с помощью модулей ES2015, затем объедините их в один файл для эффективного использования в браузерах и Node.js. Это похоже на использование Browserify и webpack. Вы можете также назвать Rollup инструментом построения, который стоит на одном ряду с такими инструментами как Grunt и Gulp. Тем не менее, важно отметить, что, хотя вы можете использовать Grunt и Gulp для решения задач пакетной обработки JavaScript, эти инструменты будут использовать подобный функционал Rollup, Browserify или webpack.

Почему вам может помочь Rollup?


Что может делать Rollup точно, дак это формировать по настоящему оптимизированные по размеру файлы. И если без скучных и нудных формальностей, то подытожить можно так: по сравнению с другими средствами для пакетной обработки JavaScript, Rollup почти всегда будет создавать меньший по объему пакет, и делать это быстрее.

Это происходит потому, что Rollup основан на модулях ES2015, которые являются более эффективными, чем модули CommonJS, которые используются в Browserify и webpack. Кроме того, Rollup гораздо проще удалить неиспользуемый код из модулей используя tree-shaking, что в итоге означает, что только тот код, который нам действительно нужен, будет включен в окончательный пакет.

Tree-shaking становится очень эффективным, когда мы используем сторонние библиотеки или фреймворки, в которых есть десятки доступных функций и методов. Если мы используем только один или два метода — например, lodash или jQuery — то загрузка библиотеки полностью несет за собой много лишних накладных расходов.

В настоящее время Browserify и webpack при сборке включают в себя много неиспользуемого кода. Но Rollup этого не делает — в сборку включается только то, что мы фактически используем.

UPDATE (2016-08-22)
Для прояснить: Rollup может использовать tree-shaking только на ES-модулях. К модулям CommonJS, которыми, на момент написания, являются как lodash, так и jQuery, не может быть применен tree-shaking. Тем не менее, tree-shaking — это одно из преимуществ Rollup на ряду с основным в виде соотношения скорость/производительность. Смотрите так же пояснение Ричарда Харриса и дополнительную информацию Нолана Лоусона.

Примечание
Частично из-за эффективности Rollup, webpack 2 будет иметь поддержку tree-shaking.

Как использовать Rollup для обработки и сборки JavaScript-файлов?


Чтобы показать, насколько эффективен Rollup, давайте рассмотрим процесс создания чрезвычайно простого проекта, который использует Rollup для сборки JavaScript.

ШАГ 0: СОЗДАНИЕ ПРОЕКТА С JAVASCRIPT И CSS.


Для начала нам нужно иметь код, с которым можно работать. В этом уроке мы будем работать с небольшим приложением, доступным на GitHub.

Структура папки выглядит так:

learn-rollup/
├── build/
│ └── index.html
├── src/
│ ├── scripts/
│ │ ├── modules/
│ │ │ ├── mod1.js
│ │ │ └── mod2.js
│ │ └── main.js
│ └── styles/
│ └── main.css
└── package.json


Вы можете установить приложение, с которым мы будем работать во время этого руководства, выполнив следующую команду в своем терминале.

# Move to the folder where you keep your dev projects.
cd /path/to/your/projects

# Clone the starter branch of the app from GitHub.
git clone -b step-0 --single-branch https://github.com/jlengstorf/learn-rollup.git

# The files are downloaded to /path/to/your/projects/learn-rollup/

Примечание
Если вы не клонируете repo, обязательно скопируйте содержимое build/index.html в свой собственный код. В этом руководстве HTML не рассматривается.

ШАГ 1: УСТАНОВКА ROLLUP И СОЗДАНИЕ ФАЙЛА КОНФИГУРАЦИИ.


Чтобы начать работу, установите Rollup с помощью следующей команды:

npm install --save-dev rollup

Затем создайте новый файл с именем rollup.config.js в папке learn-rollup. В него добавьте следующее.

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
};

Давайте поговорим о каждой опции данной конфигурации:

  • Entry — это файл, который мы хотим, чтобы Rollup обрабатывал. В большинстве приложений это будет основной JavaScript-файл, который инициализирует все и является точкой входа.
  • Dest — это место, где будут сохранены обработанные скрипты.
  • Format — Rollup поддерживает несколько форматов вывода. Поскольку мы работаем в браузере, мы хотим использовать немедленно вызываемые функции (IIFE)

    Сноска
    Это довольно сложная концепция для понимания, но если в двух словах, мы хотим, чтобы наш код находился внутри своей собственной области видимости, которая предотвращает конфликты с другими скриптами. IIFE — это замыкание, которое содержит весь наш код в его собственной области видимости.

  • SourceMap — это очень полезно для отладки, чтобы предоставить карту исходного кода. Эта опция добавляет карту к сгенерированному файлу, что упрощает данную задачу.

Примечание
Для более подробной информации по опции format, см. Rollup's Wiki.

ПРОВЕРКА КОНФИГУРАЦИИ ROLLUP

После того, как мы создали файл конфигурации, мы можем проверить, что все работает, запустив следующую команду в нашем терминале:

./node_modules/.bin/rollup -c

Это создаст новую папку под названием build в вашем проекте с подпапкой js, которая будет содержать наш сгенерированный файл main.min.js.

Мы увидим, что пакет был создан правильно, открыв build/index.html в нашем браузере:

image

Примечание
На этом этапе только современные браузеры будут работать без ошибок. Чтобы этот код работал со старыми браузерами, которые не поддерживают ES2015 / ES6, нам нужно добавить некоторые плагины.

РАЗБИРАЕМ СГЕНЕРИРОВАННЫЙ ПАКЕТ

Использование tree-shaking делает Rollup мощным инструментом, и благодаря чему в выходном файле нет неиспользованного кода из модулей, на которые мы ссылаемся. Например, в src/scripts/modules/mod1.js есть функция sayGoodbyeTo (), которая не используется в нашем приложении — и поскольку она никогда не используется, Rollup не включает ее в итоговый пакет:

Код

(function () {
'use strict';

/**
 * Says hello.
 * @param  {String} name a name
 * @return {String}      a greeting for `name`
 */
function sayHelloTo( name ) {
  const toSay = `Hello, ${name}!`;

  return toSay;
}

/**
 * Adds all the values in an array.
 * @param  {Array} arr an array of numbers
 * @return {Number}    the sum of all the array values
 */
const addArray = arr => {
  const result = arr.reduce((a, b) => a + b, 0);

  return result;
};
<habracut/>
// Import a couple modules for testing.
// Run some functions from our imported modules.
const result1 = sayHelloTo('Jason');
const result2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${result1}\n\n`
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${result2}`;

}());
//# sourceMappingURL=data:application/json;charset=utf-8;base64,...


В других инструментах сборки это не всегда так, и сгенерированные пакеты могут быть действительно большими, если мы включим большую библиотеку, такую как lodash, для ссылки на одну или две функции.

Например, с помощью webpack включена функция sayGoodbyeTo (), и полученный в результате пакет более чем в два раза превышает размер, который генерирует Rollup.

Сноска
Однако важно помнить, что, когда мы имеем дело с таким небольшим тестовыми приложениями, удвоение размера файла не занимает много времени. Для сравнения на данный момент этот размер составляет ~ 3KB против ~ 8KB

ШАГ 2: УСТАНОВИТЕ BABEL, ЧТО БЫ ИСПОЛЬЗОВАТЬ НОВЫЕ ВОЗМОЖНОСТИ JAVASCRIPT СЕЙЧАС


На данный момент у нас есть код, который будет работать только в современных браузерах, и не будет работать в некоторых браузерах, версия которых отстает на несколько версий — и это не идеально.

К счастью, Babel может нам помочь. Этот проект позволяет трансплировать новые возможности JavaScript (ES6/ES2015 и т.д.) в ES5, и данный код будет работать практически в любом браузере, который все еще может использоваться сегодня.

Если вы никогда не пользовались Babel, ваша жизнь разработчика изменяться навсегда. Доступ к новым функциям JavaScript делает язык проще, чище и приятнее в целом.

Поэтому давайте сделаем его частью нашего процесса сборки, чтобы об этом больше не думать.

УСТАНОВКА НЕОБХОДИМЫХ МОДУЛЕЙ

Сперва, нам нужно установить плагин Babel Rollup и соответствующие Babel-пресеты.

# Install Rollup’s Babel plugin.
npm install --save-dev rollup-plugin-babel

# Install the Babel preset for transpiling ES2015.
npm install --save-dev babel-preset-es2015

# Install Babel’s external helpers for module support.
npm install --save-dev babel-plugin-external-helpers

Примечание
Babel-пресеты представляет собой набор плагинов Babel, которые указывают Babel, что мы на самом деле хотим трансплировать

СОЗДАНИЕ .babelrc.

Затем создайте новый файл с именем .babelrc в корневом каталоге проекта (learn-rollup/). Внутри добавьте следующий JSON:

{
  "presets": [
    [
      "es2015",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    "external-helpers"
  ]
}

Это сообщает Babel, какой пресет он должен использовать во время трансплирования.

Примечание
В более ранних версиях npm (<v2.15.11) вы можете увидеть ошибку с пресетом es2015-rollup. Если вы не можете обновить npm, см. эту проблему для альтернативной конфигурации .babelrc.

UPDATE (2016-11-13)
В видео .babelrc использует устаревшую конфигурацию. См. этот pull request для изменения конфигурации, и этот для изменений в package.json.

ОБНОВЛЕНИЕ rollup.config.js.

Чтобы добавить Babel к Rollup, нужно обновить rollup.config.js. Внутри мы импортируем плагин Babel, а затем добавляем его в новое свойство конфигурации, называемое plugins, которое будет содержать массив плагинов.


// Rollup plugins
import babel from 'rollup-plugin-babel';

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    babel({
      exclude: 'node_modules/**',
    }),
  ],
};

Чтобы избежать транплирования сторонних скриптов, мы устанавливаем свойство exclude для игнорирования каталога node_modules.

ПРОВЕРКА ВЫХОДНОГО ПАКЕТА

Со всем установленным и настроенным, мы можем сделать ребилд пакета:

./node_modules/.bin/rollup -c

Когда мы смотрим на результат, то он выглядит примерно так же. Но есть несколько ключевых отличий: например, посмотрите на функцию addArray ():


var addArray = function addArray(arr) {
  var result = arr.reduce(function (a, b) {
    return a + b;
  }, 0);

  return result;
};

Посмотрите, как Babel преобразовал «жирную» стрелку для функции (arr.reduce ((a, b) => a + b, 0)) в обычную функцию.

Это транспиляция в действии: результат тот же, но код теперь поддерживается в IE9.

Важно
Babel также предлагает babel-polyfill, что делает вещи вроде Array.prototype.reduce () доступными в IE8 и более раних версиях.

ШАГ 3: ДОБАВЛЕНИЕ ESLINT ДЛЯ ПРОВЕРКИ JAVASCRIPT НА ОШИБКА


Всегда полезно использовать linter для вашего кода, поскольку он обеспечивает согласованную практику кодирования и помогает находить сложные ошибки, например отсутствующие операторные или круглые скобки.

Для этого проекта мы будем использовать ESLint.

УСТАНОВКА МОДУЛЯ

Чтобы использовать ESLint, нам необходимо установить плагин ESLint Rollup:

npm install --save-dev rollup-plugin-eslint

ГЕНЕРИРОВАНИЕ .eslintrc.json.

Чтобы убедиться, что мы получаем только ошибки, которые нам нужны, мы должны сначала настроить ESLint. К счастью, мы можем автоматически создать большую часть этой конфигурации, выполнив следующую команду:

Терминал

$ ./node_modules/.bin/eslint --init
? How would you like to configure ESLint? Answer questions about your style
? Are you using ECMAScript 6 features? Yes
? Are you using ES6 modules? Yes
? Where will your code run? Browser
? Do you use CommonJS? No
? Do you use JSX? No
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JSON
Successfully created .eslintrc.json file in /Users/jlengstorf/dev/code.lengstorf.com/projects/learn-rollup


Если вы ответите на вопросы, как показано выше, вы получите следующий результат в .eslintrc.json:

.eslintrc.json
{
  "env": {
    "browser": true,
    "es6": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "sourceType": "module"
  },
  "rules": {
    "indent": [
      "error",
      4
    ],
    "linebreak-style": [
      "error",
      "unix"
    ],
    "quotes": [
      "error",
      "single"
    ],
    "semi": [
      "error",
      "always"
    ]
  }
}


TWEAK .eslintrc.json

Однако мы должны внести несколько корректировок, чтобы избежать ошибок для нашего проекта:

  1. Мы используем 2 пробела вместо 4.
  2. Позднее мы будем использовать глобальную переменную, названную ENV, поэтому нам нужно занести ее в белый список.

Внесите следующие изменения в свою настройку .eslintrc.json — свойство globals и настройку свойства indent:

.eslintrc.json
{
  "env": {
    "browser": true,
    "es6": true
  },
  "globals": {
    "ENV": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "sourceType": "module"
  },
  "rules": {
    "indent": [
      "error",
      2
    ],
    "linebreak-style": [
      "error",
      "unix"
    ],
    "quotes": [
      "error",
      "single"
    ],
    "semi": [
      "error",
      "always"
    ]
  }
}


ОБНОВЛЕНИЕ rollup.config.js

Затем импортируйте плагин ESLint и добавьте его в конфигурацию Rollup:


// Rollup plugins
import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint';

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    eslint({
      exclude: [
        'src/styles/**',
      ]
    }),
    babel({
      exclude: 'node_modules/**',
    }),
  ],
};

ПРОВЕРКА РЕЗУЛЬТАТОВ В КОНСОЛИ

Когда мы запускаем ./node_modules/.bin/rollup -c, похоже, ничего не происходит. Дело в том, что код приложения в его нынешнем виде проходит linter без проблем.

Но если мы введем проблему, например удаление точки с запятой, мы увидим, как ESLint помогает:


$ ./node_modules/.bin/rollup -c

/Users/jlengstorf/dev/code.lengstorf.com/projects/learn-rollup/src/scripts/main.js
  12:64  error  Missing semicolon  semi

 1 problem (1 error, 0 warnings)

Потенциально что может содержать скрытую ошибку, теперь сразу же видно, включая файл, строку и столбец, где обнаружена проблема.

Хотя это не избавит нас от всех наших ошибок при отладке, но это значительно ускоряет данный процесс, исключая ошибок, вызванных очевидными опечатками.

Сноска
Наверное многие из нас потратили многочисленные часы, отлавливая ошибки, которые в итоге оказались чем-то таким же глупым, как название с ошибкой, трудно преувеличить повышение эффективности работы от использования линтера.

ШАГ 4: ДОБАВЛЕНИЕ ПЛАГИНА ДЛЯ ОБРАБОТКИ НЕ ES-МОДУЛЕЙ


Это важно, если вы используете в своей сборке Node-style модулей. Не используя этот плагин вы получите сообщение об ошибке при подключении данной библиотеки используя require.

ДОБАВЛЕНИЕ NODE-МОДУЛЕЙ КАК ЗАВИСИМОСТИ

Было бы легко взломать этот примерный проект без ссылки на сторонний модуль, но это не собирается сокращать его в реальных проектах. Поэтому, чтобы сделать нашу настройку Rollup действительно полезной, давайте убедимся, что мы можем также ссылаться на сторонние модули в нашем коде.

Для простоты мы добавим простой регистратор в наш код, используя пакет debug. Начните с его установки:


npm install --save debug

Примечание
Поскольку это будет указано в основном проекте, важно использовать --save, что позволит избежать ошибки в продакшене, где devDependencies будет игнорирована.

Затем, внутри src/scripts/main.js, давайте добавим простой логинг:

main.js

// Import a couple modules for testing.
import { sayHelloTo } from './modules/mod1';
import addArray from './modules/mod2';

// Import a logger for easier debugging.
import debug from 'debug';
const log = debug('app:log');

// Enable the logger.
debug.enable('*');
log('Logging is enabled!');

// Run some functions from our imported modules.
const result1 = sayHelloTo('Jason');
const result2 = addArray([1, 2, 3, 4]);

// Print the results on the page.
const printTarget = document.getElementsByClassName('debug__output')[0];

printTarget.innerText = `sayHelloTo('Jason') => ${result1}\n\n`;
printTarget.innerText += `addArray([1, 2, 3, 4]) => ${result2}`;


При запуске rollup, мы получаем предупреждение:


$ ./node_modules/.bin/rollup -c
Treating 'debug' as external dependency
No name was provided for external module 'debug' in options.globals – guessing 'debug'

И если мы снова запустим наш index.html, мы увидим, что в консоли ошибка ReferenceError:

image

Вот, дрянь. Это не сработало.

Это происходит из-за того, что в узловых Node-модулях используется CommonJS, который несовместим с Rollup. Чтобы решить эту проблему, нам нужно добавить пару плагинов для обработки зависимостей Node и модулей CommonJS.

УСТАНОВКА ЭТИХ МОДУЛЕЙ

Чтобы обойти эту проблему, нам нужно добавить два плагина:

  1. rollup-plugin-node-resolve, что позволяет загружать сторонние модули из node_modules.
  2. rollup-plugin-commonjs, который обеспечивает поддержку подключения CommonJS-модулей.

Установите оба плагина с помощью следующей команды:

npm install --save-dev rollup-plugin-node-resolve rollup-plugin-commonjs

ОБНОВЛЕНИЕ rollup.config.js

Затем импортируйте его в конфигурацию Rollup:

rollup.config.js

// Rollup plugins
import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    resolve({
      jsnext: true,
      main: true,
      browser: true,
    }),
    commonjs(),
    eslint({
      exclude: [
        'src/styles/**',
      ]
    }),
    babel({
      exclude: 'node_modules/**',
    }),
  ],
};


Примечание
Свойство jsnext обеспечивает простое мигрирование ES2015-модулей для Node-пакетов. Свойства main и browser помогают плагину решать, какие файлы следует использовать для пакета.

ПРОВЕРКА РЕЗУЛЬТАТОВ В КОНСОЛИ

Выполним ребилд командой ./node_modules/.bin/rollup -c, затем снова проверьте браузер, чтобы увидеть результат:

image

ШАГ 5: ДОБАВЛЕНИЕ ПЛАГИНА, ОБЕСПЕЧИВАЮЩЕГО ЗАМЕНУ ПЕРЕМЕННОЙ ОКРУЖЕНИЯ


Переменные среды добавляют много дополнительных «фишек» при разработке и дают нам возможность делать такие вещи, как выключение/включение логирования, внедрение только dev-скриптов и многое другое.

Поэтому давайте убедимся, что Rollup позволит нам использовать их.

ДОБАВЛЕНИЕ УСЛОВИЙ ДЛЯ ENV В main.js

Давайте воспользуемся переменной окружения и включим логирования только в том случае, если мы не в продакшен режиме. В src/scripts/main.js, изменим способ инициализации нашего log():


// Import a logger for easier debugging.
import debug from 'debug';
const log = debug('app:log');

// The logger should only be disabled if we’re not in production.
if (ENV !== 'production') {

  // Enable the logger.
  debug.enable('*');
  log('Logging is enabled!');
} else {
  debug.disable();
}

Однако после того, как мы ребилдим наш проект (./node_modules/.bin/rollup -c) и посмотрим браузер, мы увидим, что это дает нам ReferenceError для ENV.

Это не должно удивлять, потому что мы не определили его нигде. Но если мы попробуем что-то вроде ENV = production ./node_modules/.bin/rollup -c, он все равно не сработает. Это связано с тем, что установка переменной среды таким образом делает ее доступной только для Rollup, а не к пакету, созданному с помощью Rollup.

Нам нужно использовать плагин для передачи наших переменных окружения в пакет.

УСТАНОВКА ЭТИХ МОДУЛЕЙ

Начните с установки rollup-plugin-replace, которая по существу является просто утилитой find-and-replace. Он может делать много вещей, но для наших целей мы просто найдем появление переменной среды и заменим ее фактическим значением (например, все вхождения ENV будут заменены на «production» в сборке).

npm install --save-dev rollup-plugin-replace

ОБНОВЛЕНИЕ rollup.config.js


Давайте в rollup.config.js импортируем его и добавим в наш список плагинов.

Конфигурация довольно проста: мы можем просто добавить список пар ключ-значение, где ключ — это строка для замены, а значение — то, чем она должна заменить.

rollup.config.js

// Rollup plugins
import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'rollup-plugin-replace';

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    resolve({
      jsnext: true,
      main: true,
      browser: true,
    }),
    commonjs(),
    eslint({
      exclude: [
        'src/styles/**',
      ]
    }),
    babel({
      exclude: 'node_modules/**',
    }),
    replace({
      exclude: 'node_modules/**',
      ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
    }),
  ],
};


В нашей конфигурации мы описываем ENV как process.env.NODE_ENV — обычный способ установки переменных окружения в приложениях Node — либо «development». Мы используем JSON.stringify (), чтобы получить значение, заключенное в двойные кавычки.

Чтобы исключить проблемы со сторонним кодом, мы также устанавливаем свойство exclude для игнорирования нашего каталога node_modules и всех пакетов, которые он содержит. (Благодарность @wesleycoder по этому вопросу).

ПРОВЕРИМ РЕЗУЛЬТАТЫ

Сделаем ребилд сборки и проверим браузер. Лог в консоли не должен отличаться от того, что было ранее. Это хорошо — это значит, что мы использовали значение по умолчанию.
Чтобы убедиться, что настройка работает запустим ребилд в продакшен режиме:

NODE_ENV=production ./node_modules/.bin/rollup -c

Примечание
В Windows используйте SET NODE_ENV = production ./node_modules/.bin/rollup -c, чтобы избежать ошибок при работе с переменными среды. Если у вас есть проблемы с этой командой, см. эту проблему для получения дополнительной информации.

Убедимся, что после перезагрузки страницы в консоль ничего не пишется:

image

ШАГ 6: ДОБАВЛЕНИЕ UGLIFYJS, ДЛЯ СЖАТИЯ И МИНИФИЦИРОВАНИЯ СГЕНЕРИРОВАННОГО СКРИПТА


Последний шаг, который мы рассмотрим в этом руководстве, заключается в добавлении UglifyJS для минификации и сжатия нашего пакета. Это может значительно уменьшить его размер, удалив комментарии, сократив имена переменных, и другие виды «очистки» кода — что делает его более или менее нечитаемым для людей, но гораздо более эффективным для доставки по сети.

УСТАНОВКА ПЛАГИНА

Мы будем использовать UglifyJS для сжатия пакета, с помощью rollup-plugin-uglify.
Установим его следующей командой:

npm install --save-dev rollup-plugin-uglify

ОБНОВЛЕНИЕ rollup.config.js

Теперь давайте добавим Uglify в нашу конфигурацию Rollup. Для удобства отладки в процессе разработки, давайте сделаем uglification только для продакшен режима:

rollup.config.js

// Rollup plugins
import babel from 'rollup-plugin-babel';
import eslint from 'rollup-plugin-eslint';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'rollup-plugin-replace';
import uglify from 'rollup-plugin-uglify';

export default {
  entry: 'src/scripts/main.js',
  dest: 'build/js/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    resolve({
      jsnext: true,
      main: true,
      browser: true,
    }),
    commonjs(),
    eslint({
      exclude: [
        'src/styles/**',
      ]
    }),
    babel({
      exclude: 'node_modules/**',
    }),
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
    }),
    (process.env.NODE_ENV === 'production' && uglify()),
  ],
};


В нашем случае мы загружаем uglify (), когда NODE_ENV имеет значение «production».

ПРОВЕРКА МИНИФИЦИРОВАННОЙ СБОРКИ

Сохраните конфигурацию, и запустите Rollup в продакшен режиме:

NODE_ENV=production ./node_modules/.bin/rollup -c

Содержимое выходного файла имеет не очень красивый вид, но зато он намного меньше. Вот скриншот того, как сейчас выглядит build/js/main.min.js:

image

Раньше наш пакет составлял ~ 42 КБ. После прогона его через UglifyJS, его размер снизился до ~ 29 КБ — мы просто сохранили более 30% на размере файла без дополнительных усилий.

Источник

Личное впечатление:

Общее впечатление о rollup у меня сложилось достаточно положительное, может по общему набору возможностей не превосходит webpack(но это все зависит от цели использования), но, по моему мнению, более легок и прост в освоении. Не говоря уже, о заявленных самими разработчиками такими фичами, как скорость работы, более эффективная компоновка выходного кода(tree-shaking) и др. Но самый главный показатель для меня это то, что он справился со всеми потребностями моих проектах, о которых обязательно напишу в следующих статьях, где я его использовал достаточно гибко.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 63
  • +5
    Хорошо, ты собираешься сесть или не являешься тобой?
    • 0
      Когда уже впилят Webassembly, чтобы можно было прогать на TS, Dart, C# etc для фронтенда и забыть все эти JS-костыли как страшный сон. Нет, мне нравится, в каком направлении движется JS, мне не нравится, как он это делает.
      • 0

        Dart можно использовать уже сейчас, об этом была статья пару дней назад:
        https://habrahabr.ru/company/wrike/blog/330900/

        • 0
          Как связан Webassembly и TS? И что вам мешает использовать TS сейчас?
          • 0
            Мне ничего не мешает, я пописываю и так. Но сама идея писать на одном языке, чтобы это превратилось в другой для меня является чем-то диким. Вот все ругают PHP, а представьте, что Zend выкинули бы что-то подобное.
            • +1

              Вы удивитесь, но именно так работают все компиляторы. Вы пишете на Си, и ваш код превращается в машинный код.

              • 0
                Вы программист и ставите в один ряд машинный код и javascript.
                • +2

                  Расскажите поподробнее, какой дискомфорт у вас возникает от того, что код, который вы пишите, превращается в Javascript, который понимает браузер?

                  • –4
                    Расскажите поподробнее, какой дискомфорт у вас возникает от того, что код, который вы пишите, превращается в Javascript, который понимает браузер?
                    какой дискомфорт? — дикий, у тех кто не знает (или не хочет знать Javascript), и пишет на «TS, Dart, C# etc для фронтенда» — само наличие «окончательного» Javascript вызывает дикий дискомфорт, так как… есть люди которые, «сволочи окаянные и подлюги» просто прямо, ну не подлецы же,… просто прямо пишут сходу на этом самом… Javascript.

                    Само наличие этих людей просто сносит у них (тех кто пишет на «TS, Dart, C# etc для фронтенда»)… крышу и вызывает дикий дискомфорт!

                    Дикий!!!

                    Имхо, конечно, имхо. (С)
                    • 0
                      Там выше пассаж про то, что я пишу на TS и не знаю JS. Я вообще больше бэкенд, если что. Но ничто человеческое мне не чуждо и JS я знаю на достаточном уровне. По поводу дискомфорта — я бы назвал это не дискомфортом, а идиотизмом. Это вынужденная мера, я понимаю. 10 дней из жизни Брендана Айка прилетели громадным ментальным страпоном нашим современникам. И снова же — я не виню его, я понимаю, что так уж вышло. Но даже с этим пониманием нельзя отрицать, что в мире JS бардак страшнейший. Диалектов вагон. Какие хочешь. Решениями это назвать сложно. Единственное — заступлюсь немножко за Dart. Как по мне — незаслуженно отброшенный язык, хотя из всего, что есть он наиболее адекватен с точки зрения законченности всей этой скороварки. А с учетом, что дело webassembly сдвинулось с мертвой точки, хоть и медленно, у него есть все шансы на бурное развитие.
                      • +2
                        Какая вам вообще разница, во что потом превращается ваш ламповый dart/ts/что_угодно? В js, в asm.js, в wasm, в экзотический байткод, в тыкву в конце концов? Вы пишите на языке другого уровня, какое вам дело до формата, понимаемого браузером?
                        Вот чем принципиально затранспайленный JS отличается от собранного wasm? Вы же явно не лазите в собранный код с лупой? Вы используете (надеюсь) сорс-мапы. Какая тогда вообще разница?
                        • 0

                          Я лазжу. Правда это наброс на бейбель, но не суть.


                          Вчера буквально наткнулся на странное поведение (с точностью до синтаксиса):


                          class A extends React.Component {
                              someCallbackMethod = () => {
                                 const result = false;
                                 console.log('result', result);
                                 return result;
                              }
                          }
                          
                          const a = new A();
                          a.someCallbackHandler();
                          
                          и вывод в консоли
                          
                          > 'result' false
                          > ReactComponent { ... }

                          Моему изумлению не было предела, когда функция возвращает не значение переменной result, а this. Пришлось лезть в сорцы, смотреть что он там накомпилил, наткнулся на эту ошибку https://github.com/babel/babel/issues/5817


                          Но да, случай невероятно редкий и это ошибка компилятора, во всяких ваших wasm будет тоже самое, только разобраться в том, что он там накомпилил, будет сложнее в разы.

                          • +1
                            Ну так, судя по тикету, это ж альфа 7 бабеля, чего вы ожидали? :)

                            А если серьезно, то, правильно, это уже проблемы компилятора, а не конечного формата, принимаемого браузером.
                          • 0
                            — То есть, это нормально, что я пишу на одном, а транспилю в другое?
                            — Какая разница?
                            — То есть, нормально?
                            — Какая разница?
                            — То есть, нормально?

                            — Чо ты мне дверь выпилил
                            • 0
                              ээээээмм…

                              да, нормально, абсолютно нормально

                              так лучше?
                              • –1
                                Ну тогда я просто не договорюсь с вами. Я же не могу поменять вашу систему ценностей. По мне — когда вкладка в браузере отжирает какие-то немыслимые ресурсы — это не нормально. А кому-то нормально. А кто-то phoneGap использует и радуется.

                                Я скажу одно — весь мир программирования начался с бэкенда и на нем стоит. Если бы что-то подобное было там в порядке вещей, программирование уже давно бы уничтожило все человечество.

                                Вместо того, чтобы создать нормальный язык (или юзать, скажем, Dart, Kotlin etc) в качестве основы для браузеров, мы будем babel.
                                • 0
                                  А при чем тут вкладки и ресурсы? Все в одну кашу?

                                  Вы как-то наивно жонглируете какими-то терминами, бэкенды, фронтенды, как будто программирование одного идеологически лучше чем программирование другого. Не все на вебе замыкается, есть десктопы, мобайлы, мейнфреймы.

                                  Вместо того, чтобы создать нормальный язык (или юзать, скажем, Dart, Kotlin etc) в качестве основы для браузеров, мы будем babel.

                                  Пожалуйста, пишите на дарте, вам кто-то мешает?
                                  • 0
                                    Я пишу на чем хочу. А также свободен высказывать свою точку зрения. Я не понимаю одного — я (как мне показалось) откровенных глупостей не писал, я никого не оскорблял (ну да, слегка безапелляционно заявляю что-то), но почему такая реакция-то? Я же не вырываю у вас ваш макбук с криками «отдай сюда, пиши на Dart или умри». Я просто как сторонний наблюдатель высказываю свое мнение.
                                  • 0

                                    Вкладка браузера может отжирать немыслимые ресурсы и если писать на ванильном JS, и на Typescript, и на Dart. Это зависит не от используемого языка, а от рук программиста в первую очередь.


                                    Если вы считаете, что переход на компиляцию Dart->WASM вместо нынешнего Dart->JS, волшебным образом даст прирост производительности, то я позволю с вами не согласиться

                                    • +1
                                      justboris
                                      Вкладка браузера может отжирать немыслимые ресурсы и если писать на ванильном JS, и на Typescript, и на Dart. Это зависит не от используемого языка, а от рук программиста в первую очередь.

                                      На JS всё же труднее создавать монстров. А вот на Dart гораздо проще.
                                      На клиент мы в данный момент грузим около 10 мегабайт сжатого кода, раньше было 5 или 6. И раньше эта цифра выглядела страшно, сейчас и подавно. Но мы тут ничего не можем сделать -продукт активно растет функционально. Разумеется, мы стремимся, чтобы отдельные куски кода грузились по требованию, но в каких-то случаях приходится подгружать весь код сразу...
                                      То есть ребята идут на рекорд — сейчас 10, через пару лет 25, через пяток — 50-100 мегов сжатого кода придёт на их клиент. — Именно поэтому им нужен… Dart — Хотя могли с таким же успехом выбрать Java в инкарнации GWT.

                                      Alexeyco
                                      По поводу дискомфорта — я бы назвал это не дискомфортом, а идиотизмом. Это вынужденная мера, я понимаю. 10 дней из жизни Брендана Айка прилетели громадным ментальным страпоном нашим современникам. И снова же — я не виню его, я понимаю, что так уж вышло. Но даже с этим пониманием нельзя отрицать, что в мире JS бардак страшнейший.
                                      Попытки внедрить «обработчики» различных языков прямо в броузер — были и неоднократно были — в виде плагинов (апплеты Java и т.п.) — но все они… провалились и сейчас довыпиливают последние остатки Flash из броузера.

                                      Ибо — JS победил окончательно и бесповоротно на клиенте в броузере.

                                      • 0

                                        Не знаю, что там происходит во Wrike и что они грузят в браузер.
                                        Зато есть демка от разработчиков Dart: https://webdev.dartlang.org/examples/ng/doc/toh-6/dashboard
                                        Общий вес JS — 500 Кб.


                                        Конечно, на ванильном JS могло бы быть меньше, но если вы не хотите наступать на грабли Javascript, то придется заплатить немножко большим бандлом.

                • +2
                  Когда? Лет через 10! Сначала его нужно сделать, потом подождать смены устаревших браузеров, затем создать компиляторы для Вашего любимого языка, затем снова обкатать эти компиляторы и уже потом… Потом, это лет через 10, Вы поймете, что самое медленное и ужасное что было в вэб-разработке, а именно dom — осталось!
                  Вашему языку придется подстраиваться под dom. Ну и не будите же Вы писать на чистом, придется ещё подождать, пока пишущие на c# или java выучат весь вэб на отлично и даже лучше, для того чтобы зазубрить основы кривого dom, чтобы написать фраймворк, который тоже нужно обкатать. А потом скажут что все это ерунда и уже придумали что-то новое! И так было, есть и будет всегда! Поэтому совет — учитесь идти в ногу со временем и для начала — научитесь учится.
                  • 0
                    "… самое медленное и ужасное что было в вэб-разработке, а именно dom — осталось!" — Да уж. А ещё там остались HTML и CSS. Вот какая беда. Да и DOM развивается.
                    А вообще умиляет паталогическая нелюбовь C#(С++)-кодеров к JavaScript, и не имеющих понятия об интерфейсах DOM, а также о том, что HTML, CSS, JavaScript и DOM — это единое целое…
                    • 0
                      Настолько же единое, на сколько v8 един с ОС. Интерфейсы dom? Вы о чем?
                      • 0
                        «Интерфейсы dom? Вы о чем? » — https://developer.mozilla.org/ru/docs/Web/Reference/API
                        Не ожидал знаете-ли такого вопроса. И причём здесь ОС? Браузеры на движке V8 могут работать в разных операционных системах, а операционные системы и не знают о V8. А что такое JavaScript без DOM, HTML и CSS? И зачем DOM без JavaScript, HTML и CSS?
                        • –1
                          Вы задали очень крутой вопрос, но сами этого не заметили. Представим себе ЯП, который работает не в браузере, а, скажем… в качестве серверной части чего-то. И вот чтобы оно заработало, вы должны написать на одном языке, потом перегнать в другой и только потом оно запустится. Если мы представим, что браузера в этой цепочке нет, то сразу возникает мысль «чо за бред, нахер это надо». Возвращаем браузер и вуаля — слышится "а чо, потранспилировать нельзя?". Наличие браузера в этой цепочке действует оправдывающе. JS стал пыхой нашей общей современности в самом плохом смысле.
                          • 0
                            Зачем такой умозрительный подход? Я понимаю, что Вам чем-то сильно насолил фронтенд, но ради этого оставить клиента, а значит и его пользователя без браузера, это уж чересчур. Да и разработчики браузеров не поймут
                            • 0
                              Мы разговариваем на разных языках
                              • 0
                                Видимо, вы говорите на суахили
                                • –1
                                  Я не говорю, что не могу ошибаться, могу. Но и цели задеть кого-то у меня нет. А вот вы злитесь. Я не психолог и не психиатр, но может вы злитесь потому, что находите мои слова не такими уж и глупыми? Может вы согласны со мной, но вам это не нравится?
                                  • –1
                                    Да бросьте, я по таким пустякам не злюсь, и с вами я просто в корне не согласен, и это прекрасно, и только поднимает настроение :)
                                    • –1
                                      Тогда не воспринимайте это всерьез, я просто не могу удержаться )))

                                      — Ты что идиот?
                                      — А чо потранспилировать нельзя?
                                      — Ты идиот?
                                      — А чо потранспилировать нельзя?
                                      — Идиот

                                      Я это не в целях оскорбления ))
                                      • –1
                                        Вы какой-то совсем поехавший :)
                                        Ладно уж, на этом разойдемся
                      • –2
                        Не так страшен бекендщик, который пришел во фронтенд как обратный случай. Когда фронтендщик выучил, как правильно костылить и думает, что это придает ему какой-то элитарности по отношению к этой челяди бэкендской.

                        Из реального опыта. Накодил человек, взращенный на всякого рода фронте. Кусок отвечал за отрисовку каментов. Итак, надо посчитать кол-во комментариев. SELECT COUNT(*) человек не знал, а если знал, то забыл. Вместо него выбирались все комментарии, далее инициализировалась переменная с нулевым значением. А потом комментарии итерировались, а переменная инкрементировалась. Так считалось кол-во комментариев.

                        Когда пишут про то, что бекендеры чего-то там не понимают. Так мы не понимаем не webassembly, не babel etc. Это все невероятно просто, мы не понимаем, как могут одновременно существовать два стандарта JS, которые превращаются один в другой, одновременно с этим TS, Flow, sass-less-scss… и самое страшное — coffeescript.

                        Когда мне нужно перевести с английского на русский, я не перевожу сначала с английского на суахили, а с него на русский.
                        • +3
                          Не так страшен бекендщик, который пришел во фронтенд
                          Уж поверьте, еще как страшен. Как слон в посудной лавке. И кончается это все в 99% случаев истериками «ой все, идите вы со своим жабаскриптом в *». Проходили, изучали.

                          Из реального опыта
                          Идиотов полно, на всех стеках.

                          мы не понимаем, как могут одновременно существовать два стандарта JS
                          Стандарт один — ECMA. Версий языка по этому стандарту несколько. Вас же не удивляяет, что в природе есть одновременно и Java 7, и Java 8?

                          и самое страшное — coffeescript.
                          Ну классика жанра просто. Наитипичнейшая классика.

                          Когда мне нужно перевести с английского на русский, я не перевожу сначала с английского на суахили, а с него на русский.
                          Пример что-то совсем корявенький.
                          Если вы пишете на английском и вас это устраивает — пожалуйста, пишите на английском. Хотите на чем-нибудь, для чего нет прямого перевода на русский — отлично, пишите тоже, только с перегоном через английский. Все же просто.

                          • –1
                            Ну если немножко — хорошо, то много должно быть еще лучше, верно? Тогда надо напилить какой-нибудь ЯП, который будет транспилироваться сначала в coffeescript, потом в es6, потом в es5, потом пару раз туда-сюда его будут гонять JVM и LLVM, а в конце мы получим архив, где будет руби-виртуальная машина и сырцы на пыхе. Ну а перед запуском каждый раз оно будет из пыхи превращать код в руби.
                            • 0
                              Вы какой-то странный. Вы вот на чем пишите, на go вроде? Вот представьте, что можете запустить свой go в браузере, но использовать нужно — о боже, какой ужас — транспайлер. Что, вам ваши моральные устои все-таки не дадут пользоваться любимым языком для решения задач?

                              Или вы не задачи решаете, а в технологии копаетесь?
                              • –1
                                Так вы меня убедили — надо транспилировать go в php.
                                • –1
                                  А при чем тут php? У вас php в браузере работает?
                          • 0
                            Если Вы что-то не понимаете, то говорите конкретно ТОЛЬКО за себя. Неужели Вы думает что можете вот так с пол пинка за пару дней выучить api для работы с дом деревом, api svg, api canvas, api file system, событийную модель, работу gui, архитектуру gui, клиентсукую архитектуру, webgl, чтобы потом взять и написать фраймвор, который будет компилироваться с вашего языка в wasm? Или Выдумаете что сможете с помощью wasm написать фраймворк, который будет работать быстрее чем v8 от гугла, который десятилетие сотни человек пишут? Да фиг Вам! Поэтому прежде чем говорить что js фигня, скорее бы wasm, то подумайте, что вам-то от этого будет!

                            И лично Вы доказываете что Только Вы не можете вникнуть в клиентскую часть из-за того что препроцессоры Вам мешают. А если бы Вы были капельку осведомлены, то не говорили бы такую ерунду, ведь препроцессоры в клиентскую часть пришли из ruby, который тоже серверсайд. Поэтому в все проблемы только у Вас и у тех кто так же как и Вы не может привыкнуть к новым воротам. Это без обид, мне самому иногда сложно с чем-то мирится, но я стараюсь искать причины в себе.
                            • –1
                              Детский сад. Когда у фронтендщика нет аргументов в пользу защиты убогости стека (всего стека), начинаются обвинения «да ты просто не можешь выучить webpack» или типа того. А кто сказал, что я чего-то не понимаю в языке или во всем этом бардаке? Самое страшное, что я уже прекрасно ориентируюсь в нем.

                              По поводу остального — я даже отвечать на это не хочу, т.к. будет грубо. Вы выдумываете в голове какие-то мои фразы, а потом мне на них отвечаете. Читать забавно, но странно. Мой совет — попробуйте Dart, чтобы понять, как оно должно быть.
                              • 0
                                А можете уточнить, что именно я
                                ы выдумываете в голове какие-то мои фразы, а потом мне на них отвечаете

                                ВЫДУМАЛ?
                                • 0
                                  Ну вот начиная со второго предложения первого абзаца — это что такое было? Причем тут webgl etc?
                                  • 0
                                    Это я к тому, что в посте, к которому Вы написали коммент, было всего одно упоминание о так называемых бакэндщиках —
                                    придется ещё подождать, пока пишущие на c# или java выучат весь вэб на отлично и даже лучше, для того чтобы зазубрить основы кривого dom

                                    На что Вы пишите —
                                    Когда пишут про то, что бекендеры чего-то там не понимают.

                                    И начиная со второго предложения первого абзаца я объяснил что именно имел ввиду.

                                    Поэтому после заявлений что я пишу на убогом стеке технологий, я могу сказать лишь одно — а на каком Вы, не убогом, пишите gui? И какой по Вашему мнению лучший язык для серверного кода?
                                    • 0
                                      Go )) И я даже аргументирую. Меня подкупила простота всего — от юниттестов до бенчмарков, подсчета покрытия и так далее. Мне на сам синтаксис-то плевать. Мне нравятся целостные вещи, где нет лишней требухи.
                            • 0
                              Думается, что криворуких бекендщиков как и аналогичных фронтендов (это Ваши названия) поровну в Web-разработке. А доводить отношения между собой до прямого антагонизма — это наверное наша национальная специфика. Что касается всех этих webassembly, babel etc и проч — это не более чем текущие заморочки. То что стандарт JS меняется, как меняются и DOM, и HTML, и CSS, это означает лишь что Web — живой, и продолжает жить. Вам разве это не нравится? Кто-то из архитекторов говорил о Нью-Йорке, что его архитектура это катастрофа, но катастрофа красивая. Наверное это же можно сказать и современном Web.
                              • 0
                                Достаточно мне было всего лишь озвучить свое мнение о текущем положении дел как тут же кого-то мои слова обидели. При этом я этого совсем не планировал. Хотя выглядит забавно. А самое забавное, КАК меня пытаются переубеждать. Я все жду, что про мою мамку начнут что-нибудь писать.
                      • +2

                        Стоит заметить, что Webpack тоже не стоит на месте. Во 2й версии появилась нативная поддержка import деклараций, без Babel, и соответственно, tree-shaking оптимизация


                        А в 3й версии (да-да вышла на этой неделе), появился ModuleConcatenatioPlugin, делающий то же самое, что и Rollup. Почитать можно в официальном release post:
                        https://medium.com/webpack/webpack-3-official-release-15fd2dd8f07b

                        • 0

                          Короче походу сейчас проще со старичком maven, что для сборки java разобраться, чем с современной сборкой js. Прескорбно очень. Кучи настроек и файлов, чтобы просто проект начать… Капец… Сам страдаю, если что) в java правда на Градо перешел, так что полегче стало. Но js капец… Такое ощущение, что вообще не смотрят на какие грабли уже натыкались в старых топовых языках

                          • +1

                            А на какие грабли уже натыкались в топовых языках?

                            • 0

                              Так используйте всякие cli или репозитории-стартеры. Это как аналог архетипов в мавене. Если проект большой и сложный, конфиг будет сложный везде: как в мавене, так и в js-мире. Для небольших проектов готовые решения вполне подойдут.

                              • –1
                                Да, только в мавене и в мире ява сборка проекта — это действительно сборка, а в мире js под сборкой понимается пляска с бубнами и вызов Ктулху, чтобы превратить один es в другой es. То есть, дурацкая задача решается дурацкими же способами. А чтобы было что отвечать на вопрос «чем вы занимаетесь» даже придумали смуззи-термин «транспиляция».
                                • 0

                                  А чего дурацкого в задаче по конвертации кода в совместимый с более старыми интерпретаторами?


                                  Для Java, например, есть Retrolambda, чтобы фишки Java 8 в более старых версиях работали.

                                  • –1
                                    Если мне надо перевести текст с английского на русский, я не буду его сначала переводить на суахили… стоп… я же уже писал об этом.
                                    • 0

                                      При чем тут русский, при чем тут суахили? Цитирую:


                                      а в мире js под сборкой понимается пляска с бубнами и вызов Ктулху, чтобы превратить один es в другой es

                                      Процесс довольно однозначный, переводим ES6 -> ES5, где тут танцы?

                                      • 0
                                        Да и то с развитием браузеров переводим все меньше.
                                        • –1
                                          переводим ES6 -> ES5, где тут танцы?
                                          В одном предложении и вопрос, и ответ. Причем в обратном порядке.

                                          Не, ребят, я не хочу кого-то обвинять в чем-то, цели троллить или злить вас у меня просто нету. Просто мы пришли в программирование разными путями. Я понимаю, что сам факт транспиляции для вас является чем-то естественным. Но поверьте, это костыль. Как ни крути, но это просто вопиющий бардак.

                                          — Мы не можем развивать язык (т.к. не можем развивать браузеры) и вот вам babel для этого.
                                          — Мы не можем выстроить вокруг языка целостный инструментарий, поэтому сообщество развивается стихийно… результат — каждый день по фреймворку, полнейший раздрай. Вот буквально только что статья о новом каком-то инструменте сборки, тут же вышла новая версия webpack. Завтра что? Правильно, появится тысяча проектов, в которых будут использоваться разные решения.

                                          Такие вещи как сборка, управление зависимостями, приемочное и юниттестирование должны реализовываться из проекта в проект одними и теми же способами. Иначе инфраструктура превратится в то, что есть в JS.

                                          Сегодняшний разговор у меня оставил вообще ощущение, что веб в целом развивается очень дерьмово. Что этот стек технологий (а в основном, подходов) изначально ущербный. Не верите? Ну тогда на досуге покурите C# и посмотрите, какой там WPF. Таким мог бы быть и веб. Хотя мог ли…
                                          • –1

                                            А то в Яве не используют кодогенераторы.

                                            • –1
                                              В чем-то вы правы, в мире браузеров исторически сложившийся бардак и несовместимость. В основном это вина нежестких стандартов w3c/ecma, откуда проистекает несовместимость в разных движках и конечно любимой Майкрософт, которая хочет как лучше, а получается как всегда. Кроме этого бурное развитие всего во фронт-энде дополняет кошмар.

                                              НО.

                                              Если разобраться по сути, то окружение Джавы, С# и JS не так уж принципиально отличаются. В Java и С# существует Виртуальная машина, её ассемблер/intermediate language (e.g. MSIL) и JIT компиляция. В JS тоже самое. Браузер с его V8 или другим движком это собственно та же виртуалка, её ассемблер/IL это и есть тот самый JS, а проблема совместимости версий существует из-за необходимости поддержки старых браузеров (привет Майкрософту). И транспиляторы компилируют код из разных языков в JS так же как компиляторы из Java/Scala/C#/VB в код их виртуалок. А далее за дело берется JIT, который существует во всех них. И то, что код VM не читабелен, а код JS да, принципиального рояля не играет.
                                              Тоже можно сказать и про инструменты сборки проектов. У Java есть Maven/Gradle, у C# — MSBuild у JS много всего на выбор. Часть умирает, часть выживает.

                                              И так практически по всем пунктам. Со временем поутихнет развитие и останутся проверенные временем решения. Уйдут в небытие старые несовместимые браузеры, ужесточатся стандарты, надают по шее Майкрософту. На смену (или в дополнение) интерпретируемому JS придет нормальный IL, например webasm. Напишут компиляторы с разных языков и будет всем счастье. Устаканятся фреймворки. Может кто и до реализации WPF дойдёт (Я его реально люблю). Возможно и с CSS layout что нибудь нормальное сделают (хотя в это мне намного меньше верится, чем в победу разума над JS)

                                              Чисто для инфы, я работал на клиенте, когда серверов (в нынешнем понимании) ещё не существовало, работал на сервере и сейчас пишу на всяческом фронт-энде. Просто в большинстве знаю эту кухню и весь кошмар не по-наслышке. И, если честно, не смотря на все его недостатки, мне нравится JS.
                                              • 0
                                                Ну так es6 уже вовсю движется в правильном направлении. ООП более-менее стало приходить в норму. Но я говорил не о том. Ладно. Очень жаль, что нам так и не удалось выслушать начальника транспортного цеха.
                                • +4

                                  Да уж, еще один инструмент который стал не актуален (с релизом новой версии webpack) быстрее чем о нем перевели статью на хабре)

                                  • 0
                                    Alexeyco
                                    Ну так es6 уже вовсю движется в правильном направлении. ООП более-менее стало приходить в норму.


                                    ООП в ES6 не изменилось ни на йоту по сравнению с ООП в ES5.
                                    • 0

                                      Когда-нибудь люди это поймут и начнут уже писать на js

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.