Post

js export import (feat. commonJS, module)

PROBLEM

  • 아래와 같은 import 관련 런타임 에러를 만날 수 있음.
    • Cannot use import statement outside a module
    • Unexpected token ‘export’
    • Exception during run: ReferenceError: require is not defined in ES module scope, you can use import instead This file is being treated as an ES module because it has a ‘.js’ file extension and ‘C:...\package.json’ contains “type”: “module”. To treat it as a CommonJS script, rename it to use the ‘.cjs’ file extension.
  • 프로젝트 실행환경이 commonjsmodule 인지에 따라 객체 import, export 써야하는 키워드가 다름.

작성목적

  • packages.jsontype: commonjs 혹은 type: module 에 따라 파일 import, export 가이드 기술함.

module : export, default, import, as

  • 아래와 같이 package.jsontype 속성이 module 인 경우
1
2
3
4
{
  ...
  "type": "module"
}

package.json

  • keyword : export, export default

1모듈 1객체 내보내기 : export default

  • export
1
2
3
4
5
6
7
8
export default class User { // default 하나의 모듈(some.js) 에서 하나의 객체(User)만 내보낸다.
    constructor(name) {
      this.name = name;
    }
    sayHello() {
      console.log(this.name);
    }
  }
  • import
1
2
3
4
import User from './some.js';

const user = new User('John');
user.sayHello(); // John


export 할 모듈(.js) 내에서 선택적으로 내보내기

  • export default
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// currency-functions.js
const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기
export default {
  canadianToUs(canadian) {
    return roundTwoDecimals(canadian * exchangeRate);
  },

  usToCanadian: function (us) {
    return roundTwoDecimals(us / exchangeRate);
  },
};
  • import
1
2
3
4
5
6
import User from './some.js';
import * as currency from './currency-functions.js';

const user = new User('John');
user.sayHello();
console.log(currency.canadianToUs(30000)); // 27300


  • 클래스도 아래 꼴로 가능
  • export
1
2
3
4
5
6
7
8
9
10
11
12
//source/sample.js
export function sampleProvinceData(){
    ...
}

export class Province {
    ...
}

export class Producer {
    ...
}
  • import

  • 하나의 모듈(sample.js)에서 여러 객체들을 export 하고 있으므로 bracelet {}으로 묶어서 import 해줘야 한다.

1
2
3
4
5
6
7
8
9
import { sampleProvinceData, Province, Producer } from '../source/sample.js';
import assert from 'assert'; // node_modules에 installed

describe('sample.spec.js', function() {
    it('shortfall', function() {
        const asia = new Province(sampleProvinceData());
        assert.equal(asia.shortfall, 5);
    });
});
  • 위 import 문은 아래와 같이 쓴 것을 하나로 합쳐놓은 것임.
1
2
3
4
// import { sampleProvinceData, Province, Producer } from '../source/sample.js';
import {sampleProvinceData} from '../source/sample.js';
import {Province} from '../source/sample.js';
import {Producer} from '../source/sample.js';
  • 다른 예로 useState 기능을 쓰는 react 모듈이 있음.
1
import {useState} from 'react';

잘못된 export 예시 : typeError

1
2
3
4
5
6
// source/sample.js
export default {
    plumages(birds) {
        return new Map(birds.map(b => [b.name, plumage(b)]));
    },
    ...
1
2
3
4
// importAndUse.js
import * as sample from '../source/sample.js';
const result = sample.plumages(data);
// TypeError: sample.plumages is not a function
  • 올바른 방법
1
2
3
4
5
// source/sample.js
export function plumages(birds) {
    return new Map(birds.map(b => [b.name, plumage(b)]));
},
    ...


commonjs : require, exports, module.exports

  • 아래와 같이 package.jsontype 속성이 commonjs 인 경우
1
2
3
4
{
  ...
  "type": "commonjs"
}
  • export
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const exchangeRate = 0.91;

function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

const canadianToUs = function (canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
};

function usToCanadian(us) {
  return roundTwoDecimals(us / exchangeRate);
}

exports.canadianToUs = canadianToUs; // 내보내기 1
exports.usToCanadian = usToCanadian; // 내보내기 2
  • 선택하여 export
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const exchangeRate = 0.91;

// 안 내보냄
function roundTwoDecimals(amount) {
  return Math.round(amount * 100) / 100;
}

// 내보내기
const obj = {};
obj.canadianToUs = function (canadian) {
  return roundTwoDecimals(canadian * exchangeRate);
};
obj.usToCanadian = function (us) {
  return roundTwoDecimals(us / exchangeRate);
};
module.exports = obj;
  • import
1
2
3
4
5
6
7
const currency = require("./currency-functions");

console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(currency.canadianToUs(50));

console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));

module.exports

  • node 실행환경 콘솔에서 this.module 치고 들어가면 아래처럼 module객체 속성들이 나옴.
  • 그안에 exportspaths 있고 여기에 객체와 모듈 위치(경로) 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PS C:\dev\js\exportimport> node
Welcome to Node.js v20.11.1.
Type ".help" for more information.
> this.module
{
  id: '<repl>',
  path: '.',
  exports: {}, // exports 객체들이 여기 들어가겠지...
  filename: null,
  loaded: false,
  children: [],
  paths: [
    ...
    'C:\\node_modules',
    ...
  ]
}

참고

https://www.daleseo.com/js-module-require/
https://www.daleseo.com/js-module-import/

This post is licensed under CC BY 4.0 by the author.