평소의 패치일이었습니다. 코드를 변경하지 않고 npm 종속성을 패치하고 업그레이드했는데 갑자기 일부 단위 테스트가 실패했습니다.
이런!
Jest가 예상치 못한 토큰을 발견했기 때문에 내 테스트가 실패했습니다. Jest가 ESM 전용 패키지를 기본적으로 처리할 수 없기 때문에 실패했습니다. 실제로 Jest는 CommonJS로 작성되었습니다.
그런데 그게 무슨 뜻인가요? 그러기 위해서는 CommonJS와 ESM이 존재하는 이유를 이해해야 합니다.
웹 개발 초기에는 JavaScript가 주로 jQuery와 같은 라이브러리를 사용하여 DOM(문서 개체 모델)을 조작하는 데 사용되었습니다. 그러나 Node.js의 도입으로 인해 서버 측 프로그래밍에도 JavaScript가 사용되었습니다. 이러한 변화로 인해 JavaScript 코드베이스의 복잡성과 크기가 증가했습니다. 이에 따라 자바스크립트 코드를 체계적으로 정리하고 관리할 수 있는 구조화된 방법이 필요하게 되었습니다. 이러한 요구를 충족하기 위해 모듈 시스템이 도입되어 개발자는 코드를 관리 가능하고 재사용 가능한 단위1.
로 나눌 수 있습니다.CommonJS는 2009년에 설립되었으며 원래 이름은 ServerJS2였습니다. 이는 서버 측 JavaScript용으로 설계되었으며 모듈 정의에 대한 규칙을 제공합니다. Node.js는 CommonJS를 기본 모듈 시스템으로 채택하여 백엔드 JavaScript 개발자들 사이에서 널리 보급되었습니다. CommonJS는 모듈을 가져오기 위해 require를 사용하고 모듈을 내보내기 위해 module.exports를 사용합니다. CommonJS의 모든 작업은 동기식입니다. 즉, 각 모듈이 개별적으로 로드됩니다.
2015년 ECMAScript는 주로 클라이언트 측 개발을 목표로 하는 ECMAScript 모듈(ESM)이라는 새로운 모듈 시스템을 도입했습니다. ESM은 가져오기 및 내보내기 문을 사용하며 해당 작업은 비동기식이므로 모듈을 병렬로 로드할 수 있습니다3. 처음에 ESM은 브라우저용으로 설계된 반면 CommonJS는 서버용으로 설계되었습니다. 이는 점점 더 JS 생태계의 표준이 되었습니다. 요즘 최신 JavaScript 런타임은 두 모듈 시스템을 모두 지원합니다. 브라우저는 2017년부터 기본적으로 ESM을 지원하기 시작했습니다. 심지어 Typescript도 ESM 구문을 채택했으며, 배울 때마다 무의식적으로 ESM도 배우게 됩니다.
사실 ESM 전용 패키지보다 CommonJS(CJS) 전용 패키지가 더 많습니다4.
그러나 분명한 추세가 있습니다. ESM 전용 또는 이중 모듈 패키지의 수가 증가하는 반면 CJS 전용 패키지는 점점 줄어들고 있습니다. 이러한 추세는 ESM에 대한 선호도가 높아지고 있음을 강조하며 얼마나 많은 CJS 전용 패키지가 적극적으로 유지 관리되고 있는지에 대한 의문을 제기합니다.
CommonJS와 ESM의 흥미로운 비교에는 성능 벤치마크가 포함됩니다. 동기식 특성으로 인해 CommonJS는 require 및 import 문을 직접 사용할 때 더 빠릅니다. 다음 예를 고려해 보겠습니다.
듀얼 모듈을 지원하는 aws-sdk S3-Client를 사용했습니다. 여기서는 클라이언트를 인스턴스화한 다음 node:
로 실행합니다.
보시다시피 s3-get-files.cjs와 CommonJS가 더 빠르게 실행됩니다.
Buns Blogpost에서 영감을 얻었습니다.
그러나 JS 라이브러리를 프로덕션화하려면 번들로 묶어야 합니다. 그렇지 않으면 모든 node_module을 배송하게 됩니다. CJS, ESM에 번들로 묶을 수 있기 때문에 esbuild를 사용합니다. 이제 번들 버전으로 동일한 벤치마크를 실행해 보겠습니다.
보시다시피, s3-bundle.mjs는 이제 s3-bundle.cjs보다 빠릅니다. 이제 ESM 파일은 사용되지 않는 코드를 제거하는 프로세스인 효율적인 트리 쉐이킹으로 인해 파일 크기가 더 작아지고 로드 시간이 빨라지기 때문에 번들로 제공되지 않은 CommonJS 파일보다 훨씬 빠릅니다.
JavaScript 모듈의 미래는 의심할 여지없이 ESM을 향하고 있습니다. 이는 새로운 NodeJS 프로젝트 또는 심지어 React 프로젝트를 생성할 때 시작됩니다. 모든 튜토리얼과 기사는 import-문, 즉 ESM을 사용합니다. 기존의 많은 CommonJS 패키지에도 불구하고 더 많은 개발자와 유지관리자가 성능 이점과 최신 구문을 위해 ESM을 채택함에 따라 추세가 바뀌고 있습니다. 또 다른 질문은 이러한 CJS 전용 프로젝트 중 얼마나 많은 것이 아직도 유지되고 있느냐는 것입니다.
ESM は、NodeJS、Bun、Deno などのあらゆるランタイムで、サーバー上で実行せずにブラウザーで動作する標準です。ブラウザは ESM を理解するため、Babel 経由で CommonJS に変換する必要はありません。 Babel を使用して別の ECMAScript バージョンに変換することはできますが、CJS に変換しないでください。
現在のすべてのランタイムと 2017 年以降のブラウザは ESM を理解するため、ESM のみで開発する必要があります。
コードが壊れた場合は、レガシーな問題が発生している可能性があります。別のツールまたはパッケージの使用を検討してください。たとえば、Jest から vitest に移行したり、ExpressJS から h3 に移行したりできます。構文は同じままです。唯一の違いは import ステートメントです。
重要なポイント:
以上がああ、CommonJS!なぜ私と一緒にESMするのですか?! CommonJS を廃止する理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。