Jak powstrzymać babel od przeniesienia 'this' do 'undefined' (i Wstawienia " use strict")

EDIT : tu nie chodzi o fat arrows. Nie chodzi też o przekazywanie tego do IFE . To pytanie związane z transpilerem.

Więc stworzyłem prosty pub-sub dla małej aplikacji, nad którą pracuję. Napisałem go w ES6, aby użyć spread/rest i zaoszczędzić trochę bólu głowy. Ustawiłem go z npm i gulp, aby go przetransportować, ale doprowadza mnie to do szału.

Zrobiłem z niej bibliotekę przeglądarkową, ale zdałem sobie sprawę, że może być używana wszędzie, więc postanowiłem ją Kompatybilny z Commonjs i AMD.

Oto skrócona wersja mojego kodu:

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

Ale bez względu na to, co próbuję (na przykład zrobić zmienną i przekazać ją) ustawia ją na undefined .

}(undefined, function() {

To pewnie ma coś wspólnego z tym, że Babel nie wie, co to będzie i nie wie, co to będzie, ale czy jest jakieś inne podejście, które mogę przyjąć?

UPDATE : Przejście }((window || module || {}), function() { zamiast to wydaje się działać. Nie jestem pewien, czy to jest najlepsze podejście.

Author: loganfsmyth, 2016-01-24

2 answers

Dla Babel > = 7.x

Kod ES6 ma dwa tryby przetwarzania:

    Skrypt (ang. script) - gdy ładujesz plik za pomocą <script>, lub innego standardowego sposobu ładowania pliku ES5
  • "moduł" - gdy plik jest przetwarzany jako moduł ES6
W Babel 7.x, pliki są domyślnie przetwarzane jako "moduł". Problemem jest to, że w module ES6 this jest undefined, podczas gdy w przypadku "script" różni się to w zależności od środowiska, jak window w przeglądarce script lub exports w kodzie CommonJS. Podobnie, pliki "module" są automatycznie surowe, więc Babel wstawi "use strict";.

W Babel 7, musisz powiedzieć Babel jakiego typu jest Twój plik, jeśli chcesz uniknąć takiego zachowania. Najprostszą opcją byłoby użycie "sourceType" opcja, aby ustawić sourceType: "unambiguous" w opcjach Babel, która zasadniczo mówi Babel odgadnąć Typ (Skrypty vs moduł), na podstawie obecności instrukcji import i export. Podstawowym minusem jest to, że jest technicznie dobrze mieć moduł ES6, który nie używa import lub export, a te byłyby błędnie traktowane jako skrypty. Z drugiej strony, to naprawdę nie jest takie powszechne.

Alternatywnie, możesz użyć Babel 7 ' S "overrides" możliwość ustawienia określonych plików jako skryptów, np.

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

Oba podejścia pozwalają Babelowi wiedzieć, że niektóre pliki są typami script, a zatem nie powinny być konwertowane this na undefined.

Dla Babel

Kod ES6 ma dwa tryby przetwarzania:

    Skrypt (ang. script) - gdy ładujesz plik za pomocą <script>, lub innego standardowego sposobu ładowania pliku ES5
  • "moduł" - gdy plik jest przetwarzany jako moduł ES6

Podczas korzystania z Babel 6 i babel-preset-es2015 (lub Babel 5), Babel domyślnie zakłada, że pliki, które przetwarza są modułami ES6. Problem polega na tym, że w module ES6 this jest undefined i wszystkie pliki są ścisłe, podczas gdy w przypadku" script " this różni się w zależności od środowiska, jak window w skrypcie przeglądarki lub exports w kodzie CommonJS.

Jeśli używasz Babel, najprostszą opcją jest napisanie kodu bez owijarki UMD, a następnie spakowanie pliku za pomocą czegoś takiego jak Browserify, aby automatycznie dodać owijarkę UMD. Babel dostarcza również babel-plugin-transform-es2015-modules-umd. Oba są nastawione na prostotę, więc jeśli chcesz niestandardowego podejścia UMD, mogą nie być dla Ciebie.

Alternatywnie, będziesz musiał wyraźnie wyświetlić listę wszystkich wtyczek Babel w babel-preset-es2015, upewniając się, że nie ma wtyczki module-processing babel-plugin-transform-es2015-modules-commonjs. Uwaga, spowoduje to również zatrzymanie automatycznego dodawania use strict, ponieważ jest to również część specyfikacji ES6, możesz dodać z powrotem babel-plugin-transform-strict-mode, Aby zachować ścisły Kod automatycznie.

Od [email protected] presety mogą przyjmować opcje, więc możesz również wykonać

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

W Twoim Babel config (.babelrc) do użycia babel-preset-es2015 z wyłączonym przetwarzaniem modułów.

 70
Author: loganfsmyth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-13 21:38:47

Ustawienie predefiniowane "es2015" domyślnie otacza wyjście Babel wspólnym opakowaniem js. Użyj " babel-preset-es2015-script "(musisz najpierw npm install --save babel-preset-es2015-script), aby wyjść dla" script " (bez modułów). To sieje spustoszenie w innych bibliotekach, które pakowałem za pomocą Babel.

Preset: https://www.npmjs.com/package/babel-preset-es2015-script

 3
Author: user2503764,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-16 01:38:24