September 13, 2021
Javascript에 모듈 시스템은 참 다양하다. node.js 환경에서 사용가능한 모듈 시트템과 브라우저에서 사용가능한 모듈시스템이 구분되며, 이에 따라 헷갈리기 쉬운 모듈 개념을 정리하는 시간을 가져보려고 한다.
ecmascrip의 표준 모듈은 아니지만 node.js 환경에서 채택한 기본 모듈 시스템이다.
function add(a, b) {
return a + b;
}
module.exports = add;모듈을 외부에서 사용하려면 “module” 전역 네임스페이스의 exports 프로퍼티에 함수를 할당한다.
const add = require('./add');
console.log(add(1, 2));require 함수와 인수로 경로를 입력하면 모듈을 불러올 수 있다.(확장자 생략 가능)
ES6(ECMA2015+) 부터 지원하는 표준 모듈 시스템이다.
node 환경에서는 package.json 파일에서 type: "module" 프로퍼티를 설정하면 그 때 부터는 모듈 시스템이 import export로 변경된다. 이때 commonJS 방식은 사용할 수 없다.
export function add(a, b) {
return a + b;
}ESM은 모듈을 외부에서 사용하기 위해 export 키워드를 사용한다.
default export 파일 내에 단 하나의 함수만 기본 모듈로 제공하고 싶은 경우 default 키워드를 사용할 수 있다.
export function plus(a, b) {
return a + b;
}
export function minus(a, b) {
return a - b;
}
export default function add(a, b) {
return a + b;
}import add, { plus, minus } from './add.js';
...import 키워드로 모듈을 불러올 수 있다. 단 from 뒤의 모듈 경로는 반드시 파일의 확장자 단위까지 포함한 완전한 형태로 입력해야 한다. 생략이 불가능하다.
브라우저 환경에서는 ESM 방식만을 지원한다. 하지만 현대에는 React와 같은 프레임워크와 더불어 test 환경을 node.js 에서 구동시키는데, 이 같은 경우 브라우저와 node.js 환경에서 지원하는 모듈 시스템이 다르기 때문에 문제가 발생할 수 있다.
이 때는 package.json 에서 type: module 프로퍼티를 설정해주면 문제가 해결되지만, ESM은 모든 모듈에 경로를 확장자까지 포함하여 기입해야함으로 불편한 점이 많다.
편의성을 위해 webpack은 다음과 같은 문법을 ESM 방식으로 변환한다.
import add from './add'; // import add from './add.js'
import add from './directory/'; // import add from './directory/index.js'webpack.config.js 파일을 root 경로에 만들어주고 다음과 같이 입력한다.
import path from 'path';
const __dirname = path.resolve(); // ESM 방식은 __dirname이 없다.
export default {
// module.exports
entry: ['./test.js'],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
};주의할 점
위와같이 webpack 모듈 방식을 사용할 경우, require문을 사용하지 않으면 jest 실행시 SyntaxError가 발생한다. jest가 node 환경에서 실행되니 당영한 결과다.
이럴 경우에는, 루트경로에 .babelrc 파일을 따로 만들어서 node.js 환경에서 실행될 때는 별도의 모듈 시스템이 적용되도록 분리할 수 있다.
{
"presets": [
["@babel/preset-env", {
"loose": true,
"modules": "commonjs", // <= 이부분이 중요하다. auto 혹은 commonjs로 설정
"targets": [
"defaults",
"> 1% in KR",
"not dead", // 1년이상 브라우저 관리가 되지 않은 것 dead라고 판단.
"ie 10"
]
}]
]
}