Düğüm 4'te bir ES6 sınıfı nasıl düzgün bir şekilde dışa aktarılır?


116

Bir modülde bir sınıf tanımladım:

"use strict";

var AspectTypeModule = function() {};
module.exports = AspectTypeModule;

var AspectType = class AspectType {
    // ...    
};

module.export.AspectType = AspectType;

Ancak aşağıdaki hata mesajını alıyorum:

TypeError: Cannot set property 'AspectType' of undefined
    at Object.<anonymous> (...\AspectType.js:30:26)
    at Module._compile (module.js:434:26)
    ....

Bu sınıfı nasıl dışa aktarmalı ve başka bir modülde kullanmalıyım? Başka SO soruları da gördüm, ancak çözümlerini uygulamaya çalıştığımda başka hata mesajları alıyorum.


2
ES6'da 'use strict'bir modüle veya sınıfa ihtiyacınız yoktur ; varsayılan davranıştır. Ref. 10.2.1 Katı Mod Kodu
Jason Leach

Yanıtlar:


118

Düğüm 4'te ES6 kullanıyorsanız, aktarıcı olmadan ES6 modülü sözdizimini kullanamazsınız, ancak CommonJS modülleri (Düğümün standart modülleri) aynı şekilde çalışır.

module.export.AspectType

olmalı

module.exports.AspectType

dolayısıyla "Tanımsız 'AspectType' özelliği ayarlanamıyor" hata mesajı çünkü module.export === undefined.

Ayrıca

var AspectType = class AspectType {
    // ...    
};

sadece yazabilir misin

class AspectType {
    // ...    
}

ve esasen aynı davranışı elde edin.


27
OMG exportyerine exports, bunu nasıl özledim?
Jérôme Verstrynge

1
sonunda koydum module.exports = ClassNameve iyi çalışıyor
David Welborn

113
// person.js
'use strict';

module.exports = class Person {
   constructor(firstName, lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }

   display() {
       console.log(this.firstName + " " + this.lastName);
   }
}

 

// index.js
'use strict';

var Person = require('./person.js');

var someone = new Person("First name", "Last name");
someone.display();

2
@sitrakay, bunun soruyu nasıl düzelttiğine dair bir açıklama eklemelisiniz.
Alexis Tyler

bu şu hatayı verir: Yakalanmamış TypeError: '# <Nesne>' nesnesinin salt okunur özelliği 'dışa aktarımı' atanamıyor, neden bu kadar çok oy kullanılıyor?
henon

Bence, ihracat atamasının içine bütün bir sınıf tanımı koymak, sondaki tek bir satırın aynı şeyi yapması gerektiğinde bir anti kalıptır.
user1944491

44

ECMAScript 2015 ile bunun gibi birden çok sınıfı dışa ve içe aktarabilirsiniz

class Person
{
    constructor()
    {
        this.type = "Person";
    }
}

class Animal{
    constructor()
    {
        this.type = "Animal";
    }
}

module.exports = {
    Person,
    Animal
};

o zaman onları nerede kullanıyorsun:

const { Animal, Person } = require("classes");

const animal = new Animal();
const person = new Person();

İsim çakışması durumunda veya başka isimleri tercih ederseniz, bunları şu şekilde yeniden adlandırabilirsiniz:

const { Animal : OtherAnimal, Person : OtherPerson} = require("./classes");

const animal = new OtherAnimal();
const person = new OtherPerson();

1
Yanlış. Sebep: Düğüm 4'te ES6 kullanıyorsanız, aktarıcı olmadan ES6 modülü sözdizimini kullanamazsınız, ancak CommonJS modülleri (Düğümün standart modülleri) aynı şekilde çalışır. (yukarıdaki gibi)
AaronHS

Ayrıca aynı dosyada iki sınıf bildirmemelisiniz
ariel

Özel sınıflar dışa aktarılmadığı sürece, "özel benzeri" sınıfların (tek genel sınıfa yardımcı olan) aynı dosyada olması uygundur. Henüz onları iki dosyaya dönüştürmediyseniz de kabul edilebilir. Bunu yaparken, testlerinizi de ayrı dosyalara bölmeyi unutmayın. Veya sadece durumunuz için gerekeni yapın.
TamusJRoyce

@AaronHS atıfta bulunduğunuz tam fark nedir? "Yukarıdaki" yanıtta da net değil.
user1944491

16

kullanım

// aspect-type.js
class AspectType {

}

export default AspectType;

Sonra içeri aktarmak için

// some-other-file.js
import AspectType from './aspect-type';

Daha fazla ayrıntı için http://babeljs.io/docs/learn-es2015/#modules okuyun


1
Bir olsun SyntaxError: Unexpected reserved wordtam bir kod örneği sağlayabilir?
Jérôme Verstrynge

9
verme ve alma, düğümün kullandığı V8'de uygulanmamıştır. Yine de kullanmanız gerekirmodule.exports
Evan Lucas

2
... veya transpile (yani babel), gerçekten. NodeJS çoğu ES6 özelliğine sahiptir .. / hariç (hala geçerlidir, Mayıs 2017). importexport
Frank Nocke

12

sınıf ifadesi basitlik için kullanılabilir.

 // Foo.js
'use strict';

// export default class Foo {}
module.exports = class Foo {}

-

// main.js
'use strict';

const Foo = require('./Foo.js');

let Bar = new class extends Foo {
  constructor() {
    super();
    this.name = 'bar';
  }
}

console.log(Bar.name);

4
Sadece bir uyarı, Düğümde bu, modül yükleme sırasına tabidir. Bu yüzden bunu kullanırken dikkatli olun. Bu dosyaların adlarını örnek etrafında değiştirirseniz işe yaramaz.
Dustin

12

Basitçe bu şekilde yazıyorum

AspectType dosyasında:

class AspectType {
  //blah blah
}
module.exports = AspectType;

ve şu şekilde içe aktarın:

const AspectType = require('./AspectType');
var aspectType = new AspectType;

10

Diğer cevaplardan birkaçı yaklaşıyor, ama dürüst olmak gerekirse, en temiz, en basit sözdizimi ile gitmeniz daha iyi. OP, ES6 / ES2015'te bir sınıfı ihraç etmek için bir araç talep etti. Bundan daha temiz olabileceğinizi sanmıyorum:

'use strict';

export default class ClassName {
  constructor () {
  }
}

2
Yanlış. Sebep: Düğüm 4'te ES6 kullanıyorsanız, aktarıcı olmadan ES6 modülü sözdizimini kullanamazsınız, ancak CommonJS modülleri (Düğümün standart modülleri) aynı şekilde çalışır. (yukarıdaki gibi)
AaronHS

3
Hala Düğüm 4'ü kim kullanıyor? Bunun insanların% 99'u için geçerli bir cevap olduğunu düşünüyorum.
Kasalar

Kelimenin tam anlamıyla sorunun başlığında.
AaronHS

0

Ben de aynı sorunu yaşadım. Bulduğum şey, alıcı nesneme sınıf adıyla aynı adı vermemdi. misal:

const AspectType = new AspectType();

bu işleri bu şekilde mahvetti ... umarım bu yardımcı olur


0

Bazen tek bir dosyada birden fazla sınıf bildirmem gerekir veya JetBrains editörümün bunu daha iyi anlaması nedeniyle temel sınıfları dışa aktarmak ve adlarını dışa aktarılmış tutmak istiyorum. Sadece kullanıyorum

global.MyClass = class MyClass { ... };

Ve başka bir yerde:

require('baseclasses.js');
class MySubclass extends MyClass() { ... }

1
Bu, bunu yapmanın kötü bir yolu ... bir gün çarpışmaya neden olacak .
Brad

Evet iyi. Sahip olunan projelerdeki çarpışmalarda sorun yok. Ve sınıfları yalnızca require / module.exports aracılığıyla içe aktarırsanız, sorunu modül adlarına kaydırmış olursunuz.
Jelmer Jellema

PHP'yi JavaScript'te yazmaya çalışmayı bırakın: P Şakalarını bir kenara bırakın - herkesin söylediği gibi, bu sadece kendinizi daha sonraki sorunlar için hazırlamaktır. Küreseller çok kötü bir fikir değil iyi değil çok çok kötü.
robertmain

1
Kendi kodlarını izleyemeyen insanlar içindir. Required'da kullanılan dosya adlarının da global olduğunu unutmayın. Küresel olmayan dogmanın da sınırları vardır.
Jelmer Jellema

Peki, @TimHobbs, çocukların söylediği şeyler .. "Onlar sadece, nokta" gibi şeyler. Gerçek argümanları olmayan insanlardan duyduğunuz türden argümanlar tam olarak budur. Bilirsin. NodeJs bile global kullanır. İyi belgelenmiş globallerle iyi tanımlanmış bir çerçeveye sahip olduğunuzda bir sorun bile yoktur. Bunca yıllık çalışmadan sonra, mezuniyetten ve 20 yıldır kendimi ve ailemi besledikten sonra, sadece "zaten yapmak istediğim şey" olduğunu duymak güzel. Bana bir tartışma yap ya da çocuk gibi davranmayı bırak.
Jelmer Jellema
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.