Node.js 및 ES6의 module.exports 및 내보내기 기본값


317

Node module.exports와 ES6의 차이점은 무엇입니까 export default? export defaultNode.js 6.2.2에서 시도 할 때 왜 "__ is a constructor"오류가 발생하는지 알아 내려고합니다 .

작동하는 것

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This works
module.exports = SlimShady

무엇을 하지 않습니다 작동

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This will cause the "SlimShady is not a constructor" error
// if in another file I try `let marshall = new SlimShady()`
export default SlimShady

답변:


401

문제는

  • CommonJS에서 ES6 모듈을 에뮬레이트하는 방법
  • 모듈을 가져 오는 방법

ES6에서 CommonJS로

이 문서를 작성할 당시에는 기본적으로 ES6 모듈을 지원하는 환경이 없습니다. Node.js에서 사용할 때는 Babel과 같은 것을 사용하여 모듈을 CommonJS로 변환해야합니다. 그러나 정확히 어떻게 발생합니까?

많은 사람들이 생각 module.exports = ...하는 것과 수 export default ...exports.foo ...동등 할 export const foo = .... 그러나 그것은 사실이 아니거나 적어도 바벨이 그렇게하는 방식은 아닙니다.

ES6의 default수출은 실제로도있다 라는 것을 제외하고, 수출 default은 "예약 된"이름이고 그것을 위해 특수 구문 지원이있다. Babel이 이름이 지정된 내보내기와 기본 내보내기를 컴파일하는 방법을 살펴 보겠습니다.

// input
export const foo = 42;
export default 21;

// output
"use strict";

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

여기에서 기본 내보내기가 exports객체 의 속성이되는 것처럼 볼 수 foo있습니다.

모듈 가져 오기

CommonJS를 사용하거나 ES6 import구문을 사용하여 두 가지 방법으로 모듈을 가져올 수 있습니다 .

당신의 문제 : 나는 당신이 다음과 같은 일을하고 있다고 생각합니다 :

var bar = require('./input');
new bar();

그 기대하는 것은 bar기본 수출의 값이 할당됩니다. 그러나 위의 예에서 볼 수 있듯이 기본 내보내기는 default속성에 할당됩니다 !

따라서 기본 내보내기에 액세스하려면 실제로해야합니다.

var bar = require('./input').default;

ES6 모듈 구문을 사용하면

import bar from './input';
console.log(bar);

바벨은 그것을

'use strict';

var _input = require('./input');

var _input2 = _interopRequireDefault(_input);

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

console.log(_input2.default);

에 대한 모든 액세스가 access로 bar변환 되었음을 알 수 있습니다 .default.


우리는 이것에 대한 중복이 없습니까?
Bergi

3
. @Bergi가 :.! 저도 같은 문제에 대한 질문은 확실히있다 (:( 날 수치) TBH 검색하지만, 다른 방법으로 요청하지 않았다 당신이 맞는 무언가를 발견하면 알려주세요
펠릭스 클링

1
좋아, 이것들을 찾는 데 약간의 시간이 걸렸지 만 이제는 새로 얻은 능력 을 사용하고 CommonJS“require”와 함께 ES6“export default”를 올바르게 사용하는 방법 중 하나를 선택할 수 있습니까? 그리고 바벨 6.x와 () 기본 내보내기 값이 필요 없습니다 속는 대상으로 :-)
BERGI

1
내가 이것을 할 수 있다는 것이 얼마나 아이러니
한가

1
@djKianoosh : 직접 참조하십시오 . 에 할당 한 후 module.exports, exportsmodule.exports에 할당하므로, 서로 다른 값이 exports.defaults적용되지 않습니다 (때문에 module.exports수출됩니다 것입니다). 다시 말해, 마치 당신이 한 것처럼 정확히 동일 module.exports = { ... }합니다.
Felix Kling 2016 년

1

내보내기 기본값과 내보내기 const foo를 사용하려면 프로젝트에서 babel을 올바르게 구성해야합니다.

npm install --save-dev @babel/plugin-proposal-export-default-from

그런 다음 .babelrc에 아래 구성을 추가하십시오.

"plugins": [ 
       "@babel/plugin-proposal-export-default-from"
      ]

1

Felix Kling은 nodejs에서 module.exports를 사용하여 이름 지정된 내보내기와 함께 내보내기 기본값을 수행하는 방법을 궁금해하는 사람들을 위해 두 가지를 크게 비교했습니다.

module.exports = new DAO()
module.exports.initDAO = initDAO // append other functions a named export

// now you have
let DAO = require('_/helpers/DAO');
// DAO by default is exported class or function
DAO.initDAO()

-61

tl; dr 지금 작동 SlimShady하려면 가져 오거나 가져 오는 파일 을와 함께 Babel을 사용하여 컴파일해야합니다 'use strict'.

내가 사용하고 babel-cli내가 처음에이 오류가 발생 프로젝트에 6.18.0을.

없이 'use strict'나쁜 소식 곰

var SlimShady = require('./slim-shady');
var marshall = new SlimShady();  // uh, oh...

'엄격한 사용'하십시오

'use strict'
import SlimShady from './slim-shady'
var marshall = new SlimShady()  // all good in the hood

13
말이되지 않습니다. import선언 을 사용하는 모든 소스 는 모듈이며 이미 엄격한 소스입니다 . 실제 차이점은 가져 오기와 가져 오기의 차이점입니다.
Bergi

1
어떤 메이크업 감각을하는 일은 사용하고 import대신 require하고 export default대신 exports.default.
Corey Alix


104
이것은 내가
Jimi

4
@Jimi 그것은 전체 사이트에서 네 번째로 가장 많이 언급 된 답변이기 때문입니다.
pppery
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.