Использование параметра белого списка с внешними помощниками Babel

Я пытаюсь использовать Rollup с Babel external-helpers. Это работает, но сбрасывает кучу хелперов babel, которые мне даже не нужны, например asyncGenerator.

Документы показывают параметр белого списка, но я не могу заставить его работать

rollup.rollup({
    entry: 'src/buttonDropdown.es6',
    plugins: [
        babel({
            presets: ['react', ['es2015', { modules: false }], 'stage-2'],
            plugins: [['external-helpers', { whitelist: ['asyncGenerator'] }]]
        })
    ]
})

Вышеупомянутое не имеет никакого эффекта: все помощники Babel по-прежнему помещаются в мой результирующий пакет.

Как правильно использовать эту функцию и есть ли полный список имен помощников, которые принимает массив белого списка?

Или есть какой-то другой плагин Rollup, который я должен использовать с Rollup для автоматического «трясения дерева» внешними помощниками Babel.


person Adam Rackis    schedule 13.10.2016    source источник


Ответы (2)


Проблема

Плагин babel-plugin-external-helpers не несет ответственности за внедрение этих зависимостей в окончательный пакет. Единственное, что он контролирует, — это то, как сгенерированный код будет получать доступ к этим функциям. Например:

classCallCheck(this, Foo);
// or
babelHelpers.classCallCheck(this, Foo);

Это необходимо, поэтому все, что нужно сделать rollup-plugin-babel, это внедрить babelHelpers в каждый модуль.

Документация вводит в заблуждение, параметры whitelist отсутствуют в плагине external-helpers. Это полностью отдельный модуль и команда. линейный инструмент под названием babel-external-helpers, который фактически отвечает за создание babelHelpers.

Это rollup-plugin-babel то, что внедряет babelHelpers. И делает это с помощью трюка, чтобы разбить окончательный код на модули. Он вызывает babel-external-helpers для создания помощников, и игнорирует параметр белого списка. См. моя проблема с запросом на предоставление опции.

Такой подход правильный, потому что свертывание будет древовидно трясти неиспользуемые вспомогательные функции. Однако некоторые хелперы (например, asyncGenerator) написаны таким образом, что трудно определить, есть ли у инициализации какие-либо побочные эффекты, что предотвращает удаление во время встряхивания дерева.

Обходной путь

Я разветвил rollup-plugin-babel и создал PR, который предоставляет опцию белого списка для создания babelHelpers в параметрах плагина. Его можно использовать следующим образом:

require("rollup").rollup({
  entry: "./src/main.js",
  plugins: [
    require("rollup-plugin-babel")({
      "presets": [["es2015", { "modules": false }]],
      "plugins": ["external-helpers"],
      "externalHelpersWhitelist": ['classCallCheck', 'inherits', 'possibleConstructorReturn']
    })
  ]
}).then(bundle => {
  var result = bundle.generate({
    format: 'iife'
  });
  require("fs").writeFileSync("./dist/bundle.js", result.code);
}).then(null, err => console.error(err));

Обратите внимание, что я не публиковал дистрибутивную версию на npm, вам придется клонировать репозиторий git и собрать его с помощью rollup -c.

Решение

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

person Tamas Hegedus    schedule 16.10.2016
comment
Выдающийся - большое спасибо! Я оставлю это открытым пока, но с удовольствием очень скоро перешагну отметку в 10 000 :) - person Adam Rackis; 17.10.2016
comment
@AdamRackis Спасибо вам, это было интересное исследование. - person Tamas Hegedus; 17.10.2016

Как я обнаружил в этой конкретной проблеме на странице GitHub.

Участник Babel Hzoo предполагает, что

Сейчас пресет предназначен для того, чтобы люди могли использовать его без настройки. Если вы хотите изменить его, вам нужно будет просто определить плагины самостоятельно или создать свой собственный пресет.

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

  • Первый — методом разветвления.

    "babel": {
    "presets": [
      "es2015"
    ],
    "disablePlugins": [
        "babel-plugin-transform-es2015-modules-commonjs"
    ]
    

    }

Но если два или более человека захотят включить es2015-with-commonjs, это будет проблемой. Для этого вам нужно define your own preset или extend пресет этого модуля.

  • Второй метод предполагает сотрясение дерева, как показано на рис. эта статья сделана Dr. Аксель Раушмайер. Согласно статье webpack2 используется с Babel6. Это помогает удалить нежелательный импорт, который мог быть использован в любом месте проекта двумя способами.

    1. First, all ES6 module files are combined into a single bundle file. In that file, exports that were not imported anywhere are not exported, anymore.
    2. Во-вторых, набор minified, при исключении dead code. Поэтому сущности, которые не экспортируются и не используются внутри своих модулей, не отображаются в минимизированном пакете. Без первого шага устранение мертвого кода никогда не удалит экспорт (регистрация экспорта поддерживает его существование).

Остальные подробности можно найти в статье.

Простая реализация описана здесь.

  • Третий метод предполагает создание собственного пресета для конкретного модуля.

Создание плагина и создание собственного пресета можно осуществить согласно документации здесь

Также в качестве дополнительного совета вы также должны использовать babel-plugin-transforn-runtime. любой из ваших модулей имеет внешнюю зависимость, bundle в целом будет иметь один и тот же external dependancy независимо от того, использовали ли вы его на самом деле, что может иметь некоторые side-effects.

Также существует множество проблем с встряхиванием дерева в файле rollup.js, как видно из этого статья

Также, как показано в пресетах документации

Включено по умолчанию

Эти плагины больше не действуют, так как более новая версия Babylon включила их по умолчанию.

- async-functions (since babylon 6.9.1)
- exponentiation-operator (since babylon 6.9.1)
- trailing-function-commas (since babylon 6.9.1)**

Кроме того, loganfsmyth thread.

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

Вы не можете заносить в черный список определенные подключаемые модули, но вы можете перечислить только те, которые вам нужны, за исключением тех, которые вы не хотите запускать.

Обновление:

Согласно этой статье здесь важное обновление -

"Опция --external-helpers теперь является подключаемым модулем. Чтобы избежать многократного включения вспомогательных функций Babel, вам теперь необходимо установить и применить пакет babel-plugin-transform-runtime. , а затем требовать пакет babel-runtime в коде (да, даже если вы используете полифилл)".

Надеюсь, это может решить вашу проблему

Надеюсь, это поможет вам.

person Pritish Vaidya    schedule 15.10.2016
comment
Проблема GitHub, которой вы поделились, была о чем-то другом. Я думаю, что они говорят о настройке пресетов, хотя могу ошибаться. В любом случае пресеты теперь являются настраиваемыми (как вы можете видеть из моего обращения к es2015 выше), а в собственных документах Babel указана та самая опция белого списка, которую я пытаюсь использовать. Тем не менее, спасибо за хорошую информацию. +1 - person Adam Rackis; 15.10.2016
comment
да, пресеты теперь настраиваются, но я пытаюсь указать некоторые другие методы, которые могут быть реализованы, и могут быть включены некоторые полифиллы, которые могут вызвать некоторые побочные эффекты в вашем процессе связывания. Таким образом, webpack 2 вместе с встряхиванием дерева Babel 6 обеспечивает лучший подход в этих случаях - person Pritish Vaidya; 15.10.2016