Подтвердить что ты не робот

Как не допустить, чтобы babel перенес "this" в "undefined" (и вставил "use strict")

РЕД.. Это не о жирных стрелках. Это также не переход к IIFE. Это вопрос, связанный с транспилером.

Итак, я создал простой pub-sub для небольшого приложения, над которым я работаю. Я написал в ES6 для использования распространения/отдыха и сохранения некоторых головных болей. Я установил его с npm и gulp, чтобы перекрыть его, но это сбило меня с ума.

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

Здесь урезана версия моего кода:

(function(root, factory) {
 if(typeof define === 'function' && define.amd) {
    define([], function() {
        return (root.simplePubSub = factory())
    });
  } else if(typeof module === 'object' && module.exports) {
    module.exports = (root.simplePubSub = factory())
  } else {
    root.simplePubSub = root.SPS = factory()
  }
}(this, function() {
 // return SimplePubSub
});

Но независимо от того, что я пытаюсь (например, сделать это переменной и передавать ее), она устанавливает значение undefined.

}(undefined, function() {

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

ОБНОВЛЕНИЕ: передача }((window || module || {}), function() { вместо этого, похоже, работает. Я не уверен, что это лучший подход, хотя.

4b9b3361

Ответ 1

Для Вавилона> = 7.x

Код ES6 имеет два режима обработки:

  • "скрипт" - когда вы загружаете файл через <script> или любой другой стандартный ES5 способ загрузки файла
  • "модуль" - когда файл обрабатывается как модуль ES6

В Babel 7.x файлы по умолчанию анализируются как "модуль". Проблема, которая вызывает у вас проблемы, заключается в том, что в модуле ES6 this не undefined, тогда как в случае "script" это зависит от среды, например, window в сценарии браузера или exports в код CommonJS. Точно так же файлы "module" автоматически становятся строгими, поэтому Babel вставит "use strict"; ,

В Babel 7 вам нужно будет указать Babel, какой у вас тип файла, если вы хотите избежать такого поведения. Простейшим вариантом будет использование опции "sourceType" для установки sourceType: "unambiguous" в ваших параметрах Babel, что, по сути, говорит Babel угадывать тип (scripts vs module), основываясь на наличии операторов import и export. Основным недостатком является то, что технически хорошо иметь модуль ES6, который не использует import или export, и они будут неправильно рассматриваться как скрипты. С другой стороны, это действительно не так часто.

Кроме того, вы можете использовать опцию "overrides" Babel 7, чтобы установить определенные файлы в качестве сценариев, например

overrides: [{
  test: "./vendor/something.umd.js",
  sourceType: "script",
}],

Любой подход позволяет Бабель знать, что некоторые файлы script типа, и, следовательно, не должны иметь this преобразуется в undefined.

Для Вавилона <7.x

Код ES6 имеет два режима обработки:

  • "скрипт" - когда вы загружаете файл через <script> или любой другой стандартный ES5 способ загрузки файла
  • "модуль" - когда файл обрабатывается как модуль ES6

При использовании Babel 6 и babel-preset-es2015 (или Babel 5) Babel по умолчанию предполагает, что обрабатываемые файлы являются модулями ES6. Проблема, которая вызывает у вас проблемы, заключается в том, что в модуле ES6 this не undefined и все файлы являются строгими, тогда как в случае "сценария" this зависит от среды, например, window в сценарии браузера или exports в коде CommonJS.

Если вы используете Babel, самый простой вариант - написать свой код без оболочки UMD, а затем связать файл, используя что-то вроде Browserify, чтобы автоматически добавить оболочку UMD для вас. Babel также предоставляет babel-plugin-transform-es2015-modules-umd. Оба ориентированы на простоту, поэтому, если вам нужен индивидуальный подход UMD, они могут не подойти вам.

В качестве альтернативы, вам нужно было бы явно перечислить все плагины Babel в babel-preset-es2015, убедившись, что исключен модуль обработки модулей babel-plugin-transform-es2015-modules-commonjs plugin. Заметьте, что это также остановит автоматическое добавление use strict поскольку это тоже является частью спецификации ES6, вы можете захотеть добавить обратно babel-plugin-transform-strict-mode для автоматического поддержания строгого кода.

Начиная с [email protected] пресеты могут принимать опции, так что вы также можете сделать

{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}

в вашей конфигурации Babel (.babelrc) использовать babel-preset-es2015 с отключенной обработкой модуля.

Ответ 2

Предварительно установленная "es2015" обертывает вывод Babel в обертке commonJs по умолчанию. Используйте "babel-preset-es2015- script" (сначала вы должны npm install --save babel-preset-es2015-script) для вывода для "script" (без модулей). Это разрушало хаос в других библиотеках, которые я обертывал с помощью Babel.

Предустановка: https://www.npmjs.com/package/babel-preset-es2015-script