Babel 6, varsayılan ihracat biçimini değiştirir


195

Daha önce babel çizgiyi eklerdi module.exports = exports["default"]. Artık bunu yapmıyor. Bunun ne anlama geldiğini anlamadan önce:

var foo = require('./foo');
// use foo

Şimdi bunu yapmak zorundayım:

var foo = require('./foo').default;
// use foo

Büyük bir anlaşma değil (ve sanırım bu baştan beri olması gerekirdi). Sorun şu ki, işler eskiden çalıştığım yola bağlı olan bir sürü kodum var (çoğunu ES6 ithalatına dönüştürebilirim, ama hepsi değil). Herkes bana eski bir projeyi geçmek ve bunu düzeltmek zorunda kalmadan nasıl çalışması hakkında ipuçları verebilir (ya da bunu yapmak için bir codemod yazma hakkında bazı talimatlar oldukça kaygan olurdu).

Teşekkürler!

Misal:

Giriş:

const foo = {}
export default foo

Babel 5 ile çıktı

"use strict";

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

Babel 6 (ve es2015 eklentisi) ile çıktı:

"use strict";

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

Çıkıştaki tek farkın module.exports = exports["default"].


Düzenle

Özel sorunumu çözdükten sonra yazdığım bu blog yazısı ile ilgilenebilirsiniz: ES6 Modüllerini Yanlış Anlamak, Babil'i Yükseltmek, Gözyaşları ve Bir Çözüm


Merak ediyorum, requireBabel kullanan bir kod tabanında çalışıyorsanız hangi durumlarda ihtiyacınız var ? Muhtemelen, bundan kaçınmanıza izin verecek başka yaklaşımlar da vardır.
loganfsmyth

Webpack gibi ölü kodda bulunursa kod gerektirmez bir özellik kaldıraç: if (false) { require('./foo') }ile webpack aslında foo.jsortaya çıkan paket dahil atlayın .
kentcdodds

Ne olmak biter falseorada geçiş? Web paketi yapılandırmanızda mevcut bir koşulsa, başka bir seçenek olabilir.
loganfsmyth

Bu da beni ısırdı. Teşekkürler @kentcdodds.
Tyler McGinnis

1
Bu, bu gönderiyi bulmadan önce saatler boyunca sorunlara neden oldu. Benim tüm değiştirilmesi sona erdi export default {foo, bar}ile module.exports = {foo, bar}. Şimdi desteklenmeyen yanlış yöntemi oldukça beğendim .
stumct

Yanıtlar:



105

CommonJS dışa aktarma davranışı istiyorsanız, CommonJS'yi doğrudan kullanmanız (veya diğer yanıtta eklentiyi kullanmanız) gerekir. Bu davranış, karışıklığa neden olduğu ve bazı kişilerin örn.

export default {
  a: 'foo'
};

ve sonra

import {a} from './foo';

geçersiz ES6, ancak tanımladığınız CommonJS birlikte çalışabilirlik davranışı nedeniyle çalıştı. Maalesef her iki durumu da desteklemek mümkün değildir ve insanların geçersiz ES6 yazmalarına izin vermek, yapmaktan daha kötü bir konudur .default.

Diğer sorun, ileride adlandırılmış bir dışa aktarma eklediklerinde kullanıcıların beklenmedik olmasıydı, örneğin

export default 4;

sonra

require('./mod');
// 4

fakat

export default 4;
export var foo = 5;

sonra

require('./mod')
// {'default': 4, foo: 5}

Sana katılıyorum (ve kaydettik) önceki davranışın yanlış olduğunu, ancak sorumu sorunun nasıl çözüleceğiydi. Ben ağır yanlış davranış güveniyordu (bu sabaha kadar yanlış olduğunu fark etmedi). Her şeyi bir kerede güncellemek zorunda
kalmamayı

Geçerli davranışı elde etmek için tek düzeltme, kodunuzu doğrudan CommonJS'yi kullanacak şekilde değiştirmek veya güncelleme zamanınız olana kadar Babel 5'de kalmak olacaktır.
loganfsmyth

4
@kentcdodds biz bu çalışmaya devam etmek için bir webpack yükleyici yazabilirsiniz (veya bir babel eklentisi). Bir tane sağlamadıklarına (ya da değişikliği daha yoğun bir şekilde
duyurmalarına

Yaparsam ben ... Bu karıştı export default function () {}modül A ve import a from 'a'modül B Babel 6 ile aolur { default: function () {} }... Ben anladığımız kadarıyla exploringjs.com/es6/... bu çalışması gerekir ve ben ihraç almalısınız B işlevini, nesne değil.
49'da mamapitufo

@mamapitufo Bu işe yarayacak, ama bakmak için bir örnek olmadan neyin yanlış olduğunu söylemek zor. Sohbet etmek istiyorsanız Babel'in Slack'teki destek kanalından çekinmeyin.
loganfsmyth

33

Kütüphane yazarları için bu soruna geçici bir çözüm bulabilirsiniz.

Genellikle index.jsana alandan işaret ettiğim dosya olan bir giriş noktasım var package.json. Lib'in gerçek giriş noktasını yeniden dışa aktarmaktan başka bir şey yapmaz:

export { default } from "./components/MyComponent";

Babil sorununa geçici bir çözüm bulmak için, bunu bir importifadeye değiştirdim ve sonra varsayılanı atarım module.exports:

import MyComponent from "./components/MyComponent";
module.exports = MyComponent;

Diğer tüm dosyalarım, hiçbir geçici çözüm olmadan saf ES6 modülleri olarak kalır. Bu yüzden sadece giriş noktasının biraz değişmesi gerekiyor :)

Bu, commonjs gerektirir ve aynı zamanda ES6 ithalatı için de işe yarayacaktır, çünkü babel ters birlikte çalışmayı bırakmamış gibi görünmektedir (commonjs -> es6). Babel, ortakları düzeltmek için aşağıdaki işlevi enjekte eder:

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

Ben bununla mücadele saat geçirdim, bu yüzden umarım bu başkasını çabadan kurtarır!


Nedense, benim kafaları sağa hakkında spinned var asla module.exportsve export defaultşeyler. Şimdi kareye geri mi döndük?
windmaomao

@windmaomao ne demek istiyorsun? Bu bir numaradır, böylece ortak kullanıcıların kullanması gerekmez require("whatever").default. Bir kütüphane yazarı değilseniz, bu muhtemelen alakasızdır
WickyNilliams

1

Bu tür bir sorun yaşadım. Ve bu benim çözümüm:

//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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.