[번역] CommonJS가 자바스크립트를 해치고 있습니다

eunbinn·2023년 7월 24일
32

FrontEnd 번역

목록 보기
22/38
post-thumbnail
post-custom-banner

원문: https://deno.com/blog/commonjs-is-hurting-javascript

웹 개발의 부동의 왕인 자바스크립트가 경쟁 언어나 혁신적인 신기술이 아닌 스스로의 과거 잔재에 의해 방해를 받고 있습니다. 이 교활한 방해꾼은 다름 아닌 우리가 너무 오랫동안 용인해 온 구식 모듈 시스템인 CommonJS입니다.

CommonJS의 등장

자바스크립트가 발명된 지 약 15년 후, 자바스크립트는 브라우저를 넘어 서버로 확장되기 시작했습니다. 더욱 큰 규모의 프로젝트가 자바스크립트로 구축되기 시작하면서 자바스크립트는 많은 소스 코드를 처리할 수 있는 더 나은 방법이 필요했습니다. 즉, 모듈화가 필요했습니다.

2009년, Mozilla의 개발자 Kevin Dangoor는 변화를 주장했습니다. "서버 사이드 자바스크립트에 필요한 것"이라는 글에서 모듈 시스템을 포함해 서버 사이드 자바스크립트가 초창기에 놓쳤던 많은 부분을 설명했습니다.

자바스크립트는 다른 모듈을 포함하고 해당 모듈이 분리된 네임스페이스에 위치할 수 있는 표준 방법이 필요합니다. 네임스페이스를 사용하는 쉬운 방법은 있지만 모듈을 (단 한 번) 로드하는 표준 프로그래밍 방식은 아직 없습니다. 서버 사이드 앱에는 많은 코드가 포함될 수 있고, 이러한 표준 인터페이스를 충족하는 부분들을 혼합하여 사용할 가능성이 높기 때문에 이 점이 매우 중요합니다.
— Kevin Dangoor, 서버 사이드 자바스크립트에 필요한 것 (2009)

일주일 만에 당시 ServerJS라는 이름의 구글 그룹에 224명이 가입했는데, 여기에는 npm의 창립자인 Issac Schlueter와 Node.js의 창시자 Ryan Dahl이 포함되어 있었습니다(여기에서 그가 그룹에 Node를 소개합니다). 이 메일링 리스트는 이후 Node의 일부가 된 모듈 시스템인 CommonJS의 첫 번째 버전을 구체화하게 됩니다.

제안된 CommonJS의 구문(require(), module.exports등)은 클라이언트 사이드 자바스크립트처럼 보이지 않습니다. 이는 의도된 것이었습니다. Dangoor가 CommonJS를 브라우저 자바스크립트와 거리를 두려는 의도는 2009년 CommonJS 구글 그룹에 올린 메세지에서 분명하게 드러나 있습니다.

서버 사이드 코드에서 필요한 것은 클라이언트 사이드 코드에서 필요한 것과 다르기 때문에 Dojo나 jQuery보다는 Python과 Ruby를 참고하여 설계해야한다고 생각합니다.

Node.js 외에도 Flusspferd, GPSEE, Narwhal, Persevere, RingoJS, Sproutcore, v8cgi 등 초기 서버 사이드 자바스크립트 런타임은 CommonJS를 채택했습니다. (대부분이 핵심 CommonJS 그룹에서 만들어졌습니다)

그러나 CommonJS를 주요 모듈 시스템으로 사용하는 Node.js가 사실상 서버 사이드 자바스크립트의 런타임으로 자리 잡으면서, 더 넓은 CommonJS의 표준화 노력은 힘을 잃게 되었습니다. Node.js 구현이 표준이 되고 메인 런타임이 하나뿐인 상황에서 표준에 대한 필요성이 줄어들었기 때문입니다.

돌이켜보면 CommonJS의 목표는 Node를 발견하고 여기서 구축한 것을 활성화하는 것이었거나 적어도 그래야만 했던 것 같습니다. 원하는 방향으로 진행되지 않아 실수한 부분도 있었지만, 전반적으로 CommonJS 프로젝트 전체는 성공적이었다고 볼 수 있습니다.
— Issac Schlueter, CommonJS 표준화 교착상태 타개하기 (2013)의 코멘트

기본 모듈 시스템임에도 불구하고 CommonJS에는 몇 가지 핵심적인 문제가 있습니다.

  • 모듈 로딩이 동기식입니다. 각 모듈은 불린 순서대로 하나씩 로드되고 실행됩니다.
  • 트리셰이킹이 어렵습니다. 따라서 사용하지 않는 모듈을 제거하고 번들 크기를 최소화하기 어렵습니다.
  • 브라우저 기반이 아닙니다. 이 모든 코드가 클라이언트 사이드에서 동작하도록 하려면 번들러와 트랜스파일러가 필요합니다. 따라서 CommonJS를 사용하면 빌드 단계가 길어지거나 클라이언트와 서버의 코드를 구분해서 작성해야합니다.

2013년이 되자 CommonJS 그룹은 해체되기 시작했습니다. 그 해에 핵심 자바스크립트 언어의 업데이트를 감독하는 TC39 위원회는 이미 CommonJS 모듈의 후속작을 개발 중이었는데, 그것이 바로 ECMAScript 모듈입니다.

ECMAScript 모듈은 웹 우선입니다

TC39 위원회는 ES6 언어 스펙을 통해 드디어 자바스크립트 언어에 바로 내장된 모듈 시스템을 도입했습니다. 비동기 모듈 로딩, 브라우저와의 호환성, 정적 분석, 트리 쉐이킹을 포함하는 웹에 적합한 단일 모듈 로더 시스템을 구축하는 것이 목표입니다.

ES 모듈은 파일 시스템이 아닌 네트워크를 통해 데이터를 가져오는 것을 가정하여 더 나은 성능과 사용자 경험을 제공합니다.

이제 모듈 로딩 시스템이 언어에 바로 내장되어 있으므로 모든 사람들이 이를 사용하는 데 동의해, 더 높은 수준의 중요한 문제를 해결하는 데에 에너지를 집중할 수 있겠죠?

그렇죠..?

Node가 CJS와 ESM을 모두 지원하기로 결정합니다

ES 모듈과 CommonJS는 올드베이 시즈닝과 바닐라 아이스크림처럼 잘 어울립니다.
— Myles Borins, 모듈 모듈 모듈에서

(저는 Maryland 출신이라 좋게 들리네요.)

Borins는 Node에서 ES 모듈을 구현하는 업무를 맡은 Node '모듈 팀'의 개발자 중 한 명이었습니다. Node에 ESM을 성공적으로 추가했지만 팀은 ESM과 CJS 간의 상호 운용성에 대한 명확한 합의에 도달하지 못했습니다. CJS는 Node에 너무 깊숙이 내장되어 있었기 때문에 Node에서 떼어낼 수도 없었습니다. 즉, 상호 운용성 문제는 패키지 작성자에게 떠넘겨졌습니다.

다음은 ESM과 CJS를 모두 지원하는 모듈에서 필요한 package.json의 스니펫입니다.


"esm과 cjs를 모두 지원하는 패키지를 배포하는 것은 악몽입니다" - Wes Bos

다른 모듈 작성자는 dnt를 사용해서 CommonJS 및 ESM을 성공적으로 지원했습니다. TypeScript로 모듈을 작성하면 이 빌드 도구가 Node.js로 변환하고 ESM/CommonJS/TypeScript 선언 파일과 package.json을 생성합니다.

2023년에 CommonJS의 지원을 무시하기엔 너무 큰 문제가 된 것이 분명합니다. 이제 CommonJS는 묻어버리고 모두 ESM으로 전환해야 할 때입니다.

안녕, 모든 require에 감사드립니다

개발자가 모듈을 설치한 후 빌드 단계 없이 Node.js 또는 브라우저에서 코드를 실행할 수 있는 미래를 상상하고 있습니다.
— Myles Borins, 현시점의 ESModule 구현 및 계획 (2017)

2009년에 CommonJS는 자바스크립트에 꼭 필요했던 것이었습니다. 이 그룹은 어려운 문제를 해결하고 하루에 수백만 번씩 계속 사용되는 솔루션을 만들어냈습니다.

하지만 ESM이 표준이 되고 엣지, 브라우저, 서버리스 컴퓨팅과 같은 클라우드 기본 요소로 초점이 옮겨가면서 CommonJS는 더 이상 적합하지 않게 되었습니다. ESM은 브라우저 호환 코드를 작성할 수 있기 때문에 개발자에게는 더 나은 솔루션이며, 사용자에게는 더 나은 경험을 제공할 수 있습니다.

post-custom-banner

0개의 댓글