반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Crawling
- Nestjs
- dp
- 타입스크립트
- 알고리즘
- 프로그래머스
- ip
- Algorithm
- 그래프
- socket
- 레벨 1
- type challenge
- 쉬운 문제
- TCP
- BFS
- 백준
- 가천대
- HTTP 완벽 가이드
- 소켓
- 프로그래머스 레벨 2
- javascript
- 수학
- typescript
- HTTP
- 자바스크립트
- Node.js
- 문자열
- 타입 챌린지
- 크롤링
- dfs
Archives
- Today
- Total
kakasoo
ESM과 CommonJS의 차이 (이어서) 본문
반응형
2.6.6. 비동기 임포트
ESM의 단점은, 모듈 식별자를 실행 중에 생성할 수 없다는 점, 모든 파일의 최상위에 선언되어 제어 구문 내에 포함될 수 없다는 점이다. 이는 사용자에 따라 다른 모듈을 불러야 하는 경우에 지나친 제약이 될 수 있다. 따라서 이를 극복하기 위해 비동기 임포트 ( 동적 임포트 ) 를 제공한다.
if(true) {
require(a);
} else {
require(b);
}
// strings-ko.js
export const HELLO = '안녕하세요.'
// strings-jp.js
export const HELLO = '오하이요';
// strings-en.js
export const HELLO = '하이'
const SUPPORTED_LANGUAGES = ['ko', 'en', 'jp'];
const selectedLanguage = process.argv[2];
if (!SUPPORTED_LANGUAGES.includes(selectedLanguage)) {
console.error('The specified language is not supported');
process.exit(1);
}
const translationModule = `./strings-${seletecLanguages}.js`;
import(translationModule).then((string) => {
console.log(string.HELLO);
})
import() 연산자는 문법적으로 모듈 식별자를 인자로 취하고 모듈 객체를 Promise로 반환하는 함수와 동일하다.
node main.js ko // 실행 시 인자를 건네주면 된다.
2.6.8. 모듈의 수정
import fs from 'fs';
const originalReadFile = fs.readFile;
let mockResponse = null;
function mockedReadFile (path, cb) {
setImmediate(() => {
cb(null, mockedResponse)
})
}
export function mockEnable(responseWith) {
mockedResponse = responseWith;
fs.readFile = mockedReadFile;
}
export function mockDisable() {
fs.readFile = originalReadFile;
}
import fs from 'fs';
import { mockEnable, mockDisable } from './mock-read-file.js';
mockEnable(Buffer.from('Hello World'));
fs.readFile('fake-path', (err, data) => {
if (err) {
console.error(err);
process.exit(1);
}
console.log(data.toString());
})
mockDisable();
- 몽키 패치 방식
- readonly live binding 방식이라고 해도 객체의 특성을 이용해서 속성을 재할당할 수 있다.
- fs.readFile을 이 속성을 이용하여 재할당해 mock data만을 읽도록 수정하는 코드이다.
- 만약 readFile을 읽기 전용 라이브 바인딩으로 가져온다면 위 방식은 동작하지 않는다.
ESM 환경에서 몽키 패치는 복잡하고 신뢰하기 어렵기 때문에 jest 같은 프레임워크를 사용한다.
import fs, { readFileSync } from 'fs';
import { syncBuiltinESMExports } from 'module';
fs.readFileSync = () => Buffer.from('Hello, ESM');
syncBuiltinESMExports();
console.log(fs.readFileSync === readFileSync);
module의 syncBuiltinESMExports를 이용하여 default exports 객체에 있는 속성들의 값이,
named exports와 동일한 것으로 매핑되게 할 수 있다.
2-7.ESM과 CommonJS의 차이점과 상호 운용
- strict mode에서 실행된다.
- 참조 유실 ( strict mode로 인한 )
- require, export, module.exports, filename, dirname 등 몇 가지 참조가 정의되지 않는다.
- 대신에 import.meta에서 데이터를 꺼낼 수 있다.
- import.meta.url은 현재 모듈을 참조한다.
- 문맥 상 require()도 허용할 수 있다.
- import { createRequire } from 'module'; const require = createRequire(import.meta.url);
- ES에서의 this는 undefined, CommonJS에서의 this는 exports이다.
- ESM은 default exports에 한하여 CommonJS를 import 할 수 있다.
- JSON을 CommonJS처럼 가져올 수는 없다.
- module.createRequire을 사용해서 해결할 수 있다.
읽기 전용 라이브 바인딩
ES 모듈의 또 다른 기본적인 특성은 임포트된 모듈이 익스포트된 값에 대해 읽기 전용 라이브 바인딩된다는 개념입니다.
// count.js
export let count = 0;
export function increment() {
count++;
}
// main.js
import { count, increment } from './counter.js';
console.log(count); // 0
increment();
console.log(count); // 1
count++; // TypeError : Assignment to constant variavble!
- 언제든지 count의 값을 읽을 수 있고, increment() 함수로 변경도 가능하지만, count 변수를 직접적으로 변경시키려 할 때에는 const 로 바인딩한 값을 변경하려 할 때와 같은 에러가 발생한다.
- 이러한 특성을 읽기 전용 라이브 바인딩 ( readonly binding ) 이라고 한다.
- CommonJS는 구조분해할당, 또는 얕은 복사와 같이 동작하기 때문에 값을 바꿀 수도 있고, 문제는 모듈에서는 이러한 변화를 알지 못할 것이라는 점이다.
반응형
'프로그래밍 > JavaScript' 카테고리의 다른 글
함수가 포함된 JSON을 parse하는 방법 (0) | 2023.02.04 |
---|---|
RegExp, lookbehind (0) | 2023.01.14 |
ESM과 CommonJS의 차이 (0) | 2022.07.17 |
Node의 모듈 시스템과 require() (0) | 2022.07.17 |
Express 프레임워크 만들기(4), Router, Route, Layer (0) | 2021.05.20 |