Babel 6 ändert die Art und Weise, wie es standardmäßig exportiert
Lesezeit: 6 Minuten
kentcdodds
Früher fügte babel die Zeile hinzu module.exports = exports["default"]. Dies tut es nicht mehr. Was dies bedeutet, ist, bevor ich tun konnte:
var foo = require('./foo');
// use foo
Jetzt muss ich das machen:
var foo = require('./foo').default;
// use foo
Keine große Sache (und ich schätze, das ist es, was es die ganze Zeit hätte sein sollen). Das Problem ist, dass ich eine Menge Code habe, der davon abhing, wie die Dinge früher funktionierten (ich kann das meiste davon in ES6-Importe konvertieren, aber nicht alles). Kann mir jemand Tipps geben, wie ich den alten Weg zum Laufen bringen kann, ohne mein Projekt durchgehen und dies beheben zu müssen (oder sogar eine Anleitung, wie man einen Codemod schreibt, um dies zu tun, wäre ziemlich raffiniert).
Bin gespannt, was die Fälle wo brauchen require wenn Sie in einer Codebasis arbeiten, die Babel verwendet? Es besteht die Möglichkeit, dass es andere Ansätze gibt, mit denen Sie dies sowieso vermeiden können.
– loganfsmyth
3. November 2015 um 18:10 Uhr
Ich nutze eine Funktion von Webpack, die keinen Code erfordert, wenn sie in totem Code gefunden wird, wie: if (false) { require('./foo') } mit webpack würde das eigentlich inklusive überspringen foo.js im resultierenden Bündel.
– kentcdodds
3. November 2015 um 18:11 Uhr
Was am Ende dein ist false dort umschalten? Wenn es sich um eine Bedingung handelt, die in Ihrer Webpack-Konfiguration verfügbar ist, gibt es möglicherweise eine andere Option.
– loganfsmyth
3. November 2015 um 18:19 Uhr
Dieser hat mir stundenlang Probleme bereitet, bevor ich diesen Beitrag gefunden habe. Am Ende habe ich alle meine ersetzt export default {foo, bar} mit module.exports = {foo, bar}. Die hat mir gut gefallen falsch Methode, die jetzt nicht unterstützt wird.
Wenn Sie das CommonJS-Exportverhalten wünschen, müssen Sie CommonJS direkt verwenden (oder das Plugin in der anderen Antwort verwenden). Dieses Verhalten wurde entfernt, da es Verwirrung stiftete und zu einer ungültigen ES6-Semantik führte, auf die sich einige Leute verlassen hatten, z
export default {
a: 'foo'
};
und dann
import {a} from './foo';
Dies ist ungültiges ES6, funktionierte jedoch aufgrund des von Ihnen beschriebenen CommonJS-Interoperabilitätsverhaltens. Leider ist es nicht möglich, beide Fälle zu unterstützen, und es ist schlimmer, Leuten zu erlauben, ungültige ES6 zu schreiben, als Sie dazu zu bringen .default.
Das andere Problem war, dass es für Benutzer unerwartet war, wenn sie beispielsweise in Zukunft einen benannten Export hinzufügten
export default 4;
Dann
require('./mod');
// 4
Aber
export default 4;
export var foo = 5;
Dann
require('./mod')
// {'default': 4, foo: 5}
Ich stimme Ihnen zu (und habe festgestellt), dass das vorherige Verhalten falsch war, aber meine Frage war, wie ich das Problem umgehen kann. Ich habe mich stark auf das falsche Verhalten verlassen (habe bis heute Morgen nicht bemerkt, dass es falsch war). Ich möchte nicht alles auf einmal aktualisieren müssen…
– kentcdodds
3. November 2015 um 18:10 Uhr
Die einzige Lösung, um das aktuelle Verhalten zu erhalten, wäre, Ihren Code so umzustellen, dass er CommonJS direkt verwendet, oder auf Babel 5 zu bleiben, bis Sie Zeit zum Aktualisieren haben.
– loganfsmyth
3. November 2015 um 18:12 Uhr
@kentcdodds Wir können einen Webpack-Loader schreiben, damit dies funktioniert (oder ein Babel-Plugin). Ich bin überrascht, dass sie keine bereitstellen (oder die Änderung stärker veröffentlichen!)
– Jamund Ferguson
3. November 2015 um 18:20 Uhr
Das verwirrt mich… falls doch export default function () {} in Modul A und dann import a from 'a' in Modul B, mit Babel 6 a wäre { default: function () {} }… soweit ich das verstehen kann explorejs.com/es6/… Dies sollte funktionieren und ich sollte die exportierte Funktion in B erhalten, nicht das Objekt.
– mamapitufo
18. Januar 2016 um 16:49 Uhr
@mamapitufo Das sollte funktionieren, aber ohne ein Beispiel ist es schwer zu sagen, was falsch ist. Schauen Sie gerne bei Babels Support-Kanal auf Slack vorbei, wenn Sie chatten möchten.
– loganfsmyth
18. Januar 2016 um 17:07 Uhr
Sie können auch verwenden dieses Plugin um das alte zu bekommen export Verhalten zurück.
Ich wusste, dass jemand früher oder später ein Plugin schreiben würde. Danke!
– kentcdodds
16. November 2015 um 13:33 Uhr
Leider unterstützt babel-plugin-add-module-exports (noch) keine Module im AMD-Stil
Ich denke, die Verwendung von UMD und dieses Plugin ist der richtige Weg! Danke
– electronicix384128
21. April 2017 um 6:14 Uhr
Sehr sehr hilfreich.
– Jovica Aleksic
7. Mai 2018 um 19:56 Uhr
WickyNilliams
Für Bibliotheksautoren können Sie dieses Problem möglicherweise umgehen.
Normalerweise habe ich einen Einstiegspunkt, index.jsdas ist die Datei, auf die ich vom Hauptfeld aus zeige package.json. Es tut nichts anderes, als den tatsächlichen Einstiegspunkt der Bibliothek erneut zu exportieren:
export { default } from "./components/MyComponent";
Um das babel-Problem zu umgehen, habe ich dies in eine geändert import -Anweisung und weisen Sie dann den Standardwert zu module.exports:
import MyComponent from "./components/MyComponent";
module.exports = MyComponent;
Alle meine anderen Dateien bleiben als reine ES6-Module ohne Problemumgehungen. Also muss nur der Einstiegspunkt etwas geändert werden 🙂
Dies funktioniert für commonjs-Anforderungen und auch für ES6-Importe, da babel die Reverse Interop (commonjs -> es6) nicht fallen gelassen zu haben scheint. Babel fügt die folgende Funktion ein, um commonjs zu patchen:
Ich habe Stunden damit verbracht, dagegen anzukämpfen, also hoffe ich, dass dies jemand anderem die Mühe erspart!
Aus irgendeinem Grund habe ich nie richtig herumgewirbelt module.exports Und export default Sachen. Jetzt sind wir wieder bei Null?
– windmaomao
20. Februar 2018 um 17:44 Uhr
@windmaomao was meinst du? Dies ist ein Trick, damit Benutzer von commonjs dies nicht tun müssen require("whatever").default. Wenn Sie kein Bibliotheksautor sind, ist dies wahrscheinlich irrelevant
– WickyNilliams
21. Februar 2018 um 15:37 Uhr
Ich hatte so ein Problem. Und das ist meine Lösung:
//src/arithmetic.js
export var operations = {
add: function (a, b) {
return a + b;
},
subtract: function (a, b) {
return a - b;
}
};
//src/main.js
import { operations } from './arithmetic';
let result = operations.add(1, 1);
console.log(result);
14421800cookie-checkBabel 6 ändert die Art und Weise, wie es standardmäßig exportiertyes
Bin gespannt, was die Fälle wo brauchen
require
wenn Sie in einer Codebasis arbeiten, die Babel verwendet? Es besteht die Möglichkeit, dass es andere Ansätze gibt, mit denen Sie dies sowieso vermeiden können.– loganfsmyth
3. November 2015 um 18:10 Uhr
Ich nutze eine Funktion von Webpack, die keinen Code erfordert, wenn sie in totem Code gefunden wird, wie:
if (false) { require('./foo') }
mit webpack würde das eigentlich inklusive überspringenfoo.js
im resultierenden Bündel.– kentcdodds
3. November 2015 um 18:11 Uhr
Was am Ende dein ist
false
dort umschalten? Wenn es sich um eine Bedingung handelt, die in Ihrer Webpack-Konfiguration verfügbar ist, gibt es möglicherweise eine andere Option.– loganfsmyth
3. November 2015 um 18:19 Uhr
Dieser hat mir stundenlang Probleme bereitet, bevor ich diesen Beitrag gefunden habe. Am Ende habe ich alle meine ersetzt
export default {foo, bar}
mitmodule.exports = {foo, bar}
. Die hat mir gut gefallen falsch Methode, die jetzt nicht unterstützt wird.– stolpern
23. Januar 2016 um 16:40 Uhr
@loganfsmyth Es ist sehr nützlich, um ganze Module ohne viele Wiederholungen im Code weiterzugeben. Schauen Sie sich dieses Wesentliche an gist.github.com/loopmode/3eeaf0764c30439add1d8008e39d0267
– Jovica Aleksic
7. Mai 2018 um 20:02 Uhr