노드 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.