노드 4에서 ES6 클래스를 올바르게 내보내는 방법은 무엇입니까?


115

모듈에 클래스를 정의했습니다.

"use strict";

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

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

module.export.AspectType = AspectType;

하지만 다음과 같은 오류 메시지가 나타납니다.

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

이 클래스를 내보내고 다른 모듈에서 어떻게 사용해야합니까? 다른 SO 질문을 보았지만 솔루션을 구현하려고 할 때 다른 오류 메시지가 나타납니다.


2
ES6에서는 'use strict'모듈이나 클래스 가 필요하지 않습니다 . 기본 동작입니다. Ref. 10.2.1 Strict Mode Code
Jason Leach

답변:


117

Node 4에서 ES6를 사용하는 경우 트랜스 파일러없이 ES6 모듈 구문을 사용할 수 없지만 CommonJS 모듈 (노드의 표준 모듈)은 동일하게 작동합니다.

module.export.AspectType

해야한다

module.exports.AspectType

따라서 오류 메시지 "Undefined의 'AspectType'속성을 설정할 수 없습니다 module.export === undefined. "

또한

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

그냥 쓸 수 있어요

class AspectType {
    // ...    
}

기본적으로 동일한 동작을 얻습니다.


27
export대신 OMG exports, 어떻게 놓쳤습니까?
Jérôme Verstrynge 2015 년

1
마지막에 내가 넣어 module.exports = ClassName하고 그것을 잘 작동
데이비드 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이 질문이 어떻게 해결되는지에 대한 설명을 추가해야합니다.
Alexis Tyler

이것은 오류를 제공합니다. Uncaught TypeError : Cannot assign to read only property 'exports'of object '# <Object>'왜 이렇게 많이 업 보팅됩니까?
henon

내보내기 할당 안에 전체 클래스 정의를 넣는 것은 끝에 한 줄이 같은 일을해야 할 때 안티 패턴이라고 생각합니다.
user1944491

44

ECMAScript 2015를 사용하면 이와 같은 여러 클래스를 내보내고 가져올 수 있습니다.

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

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

module.exports = {
    Person,
    Animal
};

그런 다음 사용하는 곳 :

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

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

이름이 충돌하거나 다른 이름을 선호하는 경우 다음과 같이 이름을 바꿀 수 있습니다.

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

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

1
잘못된. 이유 : Node 4에서 ES6를 사용하는 경우 트랜스 파일러없이 ES6 모듈 구문을 사용할 수 없지만 CommonJS 모듈 (노드의 표준 모듈)은 동일하게 작동합니다. (위에 따라)
AaronHS

또한 동일한 파일에 두 개의 클래스를 선언해서는 안됩니다.
ariel

개인 클래스를 내 보내지 않는 한 동일한 파일에 "개인과 유사한"클래스 (단일 공용 클래스를 지원하는)가있는 것은 괜찮습니다. 아직 두 개의 파일로 리팩터링하지 않은 경우에도 허용됩니다. 그렇게 할 때 테스트를 별도의 파일로 분할하는 것을 잊지 마십시오. 또는 상황에 맞게 필요한 작업을 수행하십시오.
TamusJRoyce

@AaronHS 당신이 언급하는 정확한 차이점은 무엇입니까? "위"대답에서도 명확하지 않습니다.
user1944491

16

사용하다

// aspect-type.js
class AspectType {

}

export default AspectType;

그런 다음 가져 오기

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

자세한 내용은 http://babeljs.io/docs/learn-es2015/#modules 를 읽어보십시오.


1
을 얻었습니다 SyntaxError: Unexpected reserved word. 전체 코드 예제를 제공 할 수 있습니까?
Jérôme Verstrynge 2015 년

9
내보내기 및 가져 오기는 노드가 사용하는 V8에서 구현되지 않았습니다. 그래도 사용해야합니다module.exports
Evan Lucas

2
... 또는 트랜스 파일 (예 : 바벨)입니다. NodeJS에는 /를 제외한 대부분의 ES6 기능이 있습니다 . importexport
Frank Nocke 17

12

클래스 표현 은 간단하게 사용할 수 있습니다.

 // 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
경고 일뿐입니다. Node에서 이것은 모듈 로딩 순서에 따릅니다. 따라서 이것을 사용하는 데주의하십시오. 이 파일의 이름을 바꾸면 예제가 작동하지 않습니다.
Dustin

12

나는 단순히 이렇게 쓴다

AspectType 파일에서 :

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

다음과 같이 가져옵니다.

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

10

다른 답변 중 일부는 비슷하지만 솔직히 가장 깨끗하고 간단한 구문을 사용하는 것이 좋습니다. OP는 ES6 / ES2015에서 수업을 내보내는 수단을 요청했습니다. 나는 당신이 이것보다 훨씬 더 깨끗해질 수 있다고 생각하지 않습니다.

'use strict';

export default class ClassName {
  constructor () {
  }
}

2
잘못된. 이유 : Node 4에서 ES6를 사용하는 경우 트랜스 파일러없이 ES6 모듈 구문을 사용할 수 없지만 CommonJS 모듈 (노드의 표준 모듈)은 동일하게 작동합니다. (위에 따라)
AaronHS

3
도대체 누가 여전히 노드 4를 사용하고 있습니까? 저는 이것이 99 %의 사람들에게 유효한 대답이라고 생각합니다.
상자

말 그대로 질문 제목에 있습니다.
AaronHS

0

나는 같은 문제가 있었다. 내가 찾은 것은 내가받는 물건을 수업 이름과 같은 이름으로 불렀다는 것입니다. 예:

const AspectType = new AspectType();

이런 식으로 일을 망쳤습니다.이게 도움이되기를 바랍니다.


0

때로는 하나의 파일에 여러 클래스를 선언해야하거나 JetBrains 편집기가 더 잘 이해하기 때문에 기본 클래스를 내보내고 이름을 내보내고 싶습니다. 난 그냥 사용

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

그리고 다른 곳 :

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

1
이것은이 작업을 수행하는 나쁜 방법입니다 ... 그것은 것입니다 언젠가 충돌이 발생할.
Brad

그래. 소유 한 프로젝트의 충돌에 문제가 없습니다. 그리고 순수하게 require / module.exports를 통해 클래스를 가져 오면 문제를 모듈 이름으로 옮기는 것입니다.
Jelmer Jellema 2017

자바 스크립트로 PHP를 작성하려고하지 마세요. : P 농담은 제쳐두고-다른 사람들이 말했듯이 이것은 나중에 문제에 대해 스스로를 설정하는 것입니다. 전역은 아주 나쁘지 않고 아주 나쁜 생각입니다.
robertmain

1
그들은 자신의 코드를 추적 할 수없는 사람들을위한 것입니다. require에 사용 된 파일 이름도 전역이라는 것을 잊지 마십시오. 비-글로벌 교리에도 한계가 있습니다.
Jelmer Jellema

글쎄, @TimHobbs, 아이들이 말하는 것 .. "그냥 그저 그렇다." 그것이 바로 실제 논쟁이없는 사람들에게서들은 논쟁의 종류입니다. 알 잖아. NodeJ조차도 전역을 사용합니다. 잘 문서화 된 전역으로 잘 정의 된 프레임 워크가있는 경우에도 문제가 없습니다. 이 모든 수년간의 공부, 우등 졸업, 20 년 동안 나 자신과 가족에게 음식을 제공 한 후, 그것은 단지 "어쨌든 내가하고 싶은 일"일 뿐이라는 말을 들으니 기쁩니다. 나에게 말다툼을하거나 어린애처럼 행동하지 마세요.
Jelmer Jellema
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.