Babel 6 ändert die Art und Weise, wie es standardmäßig exportiert

Lesezeit: 6 Minuten

Benutzeravatar von kentcdodds
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).

Danke!

Beispiel:

Eingang:

const foo = {}
export default foo

Ausgabe mit Babel 5

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];

Ausgabe mit Babel 6 (und es2015-Plugin):

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;

Beachten Sie, dass der einzige Unterschied in der Ausgabe der ist module.exports = exports["default"].


Bearbeiten

Vielleicht interessiert Sie dieser Blogpost, den ich geschrieben habe, nachdem ich mein spezifisches Problem gelöst hatte: Missverständnisse bei ES6-Modulen, Upgrade von Babel, Tears und eine Lösung

  • 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.

    – 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

Benutzeravatar von loganfsmyth
loganfsmyth

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

    – Zower

    23. November 2015 um 9:54 Uhr

  • Ich habe die verwendet babel-plugin-transform-es2015-modules-simple-amd um dasselbe Problem in meinem Projekt mit AMD-Modulen zu lösen

    – Tom Wayson

    20. Februar 2016 um 19:52 Uhr

  • 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

Benutzeravatar von WickyNilliams
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:

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 

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

1442180cookie-checkBabel 6 ändert die Art und Weise, wie es standardmäßig exportiert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy