Node.js 빠른 소개 과정: 배우려면 입력하세요.
2년 전 저는 모듈 시스템을 소개하는 기사인 프론트 엔드 모듈의 개념 이해: CommonJs 및 ES6Module을 썼습니다. 이 기사의 지식은 초보자를 대상으로 하며 비교적 간단합니다. 여기서는 기사의 몇 가지 오류도 수정합니다.
[모듈]과 [모듈 시스템]은 서로 다른 것입니다. 모듈은 소프트웨어의 단위이고, 모듈 시스템은 개발자가 프로젝트에서 모듈을 정의하고 사용할 수 있는 구문 또는 도구 집합입니다.
ECMAScript Module의 약자는 ES6Module이 아닌 ESM, 즉 ESModule입니다.
모듈 시스템에 대한 기본 지식은 이전 기사에서 거의 다루었으므로 이 기사에서는 모듈 시스템의 내부 원리에 중점을 두고 다양한 모듈 시스템 간의 차이점에 대한 보다 완전한 소개를 제공합니다. 이전 기사의 내용은 다음과 같습니다. 다시는 반복되지 않습니다.
모든 프로그래밍 언어에 모듈 시스템이 내장되어 있는 것은 아니며, 자바스크립트도 탄생 후 오랫동안 모듈 시스템이 없었습니다.
브라우저 환경에서는 사용되지 않는 코드 파일을 도입하기 위해 <script>
태그만 사용할 수 있습니다. 이 방법은 프런트 엔드의 급속한 발전과 함께 문제가 가득하다고 할 수 있습니다. 더 이상 현재의 요구 사항을 충족합니다. 공식 모듈 시스템이 등장하기 전에 프런트 엔드 커뮤니티는 자체 타사 모듈 시스템을 만들었습니다. 가장 일반적으로 사용되는 모듈 시스템은 비동기 모듈 정의 AMD , 범용 모듈 정의 UMD 등입니다. 물론 가장 유명한 것은 CommonJS 입니다.
Node.js는 JavaScript 런타임 환경이므로 기본 파일 시스템에 직접 액세스할 수 있습니다. 그래서 개발자들은 이를 채택하여 CommonJS 사양에 따른 모듈 시스템을 구현했습니다.
처음에는 CommonJS를 Node.js 플랫폼에서만 사용할 수 있었지만 Browserify 및 Webpack과 같은 모듈 패키징 도구가 등장하면서 CommonJS는 마침내 브라우저 측에서 실행될 수 있게 되었습니다.
2015년 ECMAScript6 사양이 발표되기 전까지는 모듈 시스템에 대한 공식적인 표준이 없었습니다. 이 표준에 따라 구축된 모듈 시스템을 줄여서 ECMAScript 모듈 (ESM)이라고 부르기 시작했습니다. Node.js 환경과 브라우저 환경. 물론 ECMAScript6은 구문과 의미만 제공하므로 구현에 있어서는 다양한 브라우저 서비스 공급업체와 Node 개발자가 열심히 노력해야 합니다. 그렇기 때문에 다른 프로그래밍 언어가 부러워하는 바벨 아티팩트가 있습니다. 모듈 시스템을 구현하는 것은 쉬운 작업이 아닙니다. Node.js는 버전 13.2에서만 ESM을 비교적 안정적으로 지원합니다.
하지만 무슨 일이 있어도 ESM은 JavaScript의 "아들"이므로 배우는 데 아무런 문제가 없습니다!
화전시대에는 자바스크립트를 이용해 애플리케이션을 개발했고, 스크립트 파일은 스크립트 태그를 통해서만 도입할 수 있었다. 더 심각한 문제 중 하나는 네임스페이스 메커니즘이 없다는 것입니다. 이는 각 스크립트가 동일한 범위를 공유한다는 것을 의미합니다. 커뮤니티에는 이 문제에 대한 더 나은 해결책이 있습니다: Revevaling 모듈
const myModule = (() => { const _privateFn = () => {} const_privateAttr = 1 반품 { publicFn: () => {}, 공개 속성: 2 } })() console.log(myModule) console.log(myModule.publicFn, myModule._privateFn)
실행 결과는 다음과 같습니다.
이 패턴은 매우 간단합니다. IIFE를 사용하여 개인 범위를 만들고 반환 변수를 사용하여 노출합니다. 내부 변수(예: _privateFn, _privateAttr)는 외부 범위에서 액세스할 수 없습니다.
[공개 모듈]은 이러한 기능을 활용하여 개인 정보를 숨기고 외부에 노출되어야 하는 API를 내보냅니다. 후속 모듈 시스템도 이 아이디어를 바탕으로 개발되었습니다.
위의 아이디어를 바탕으로 모듈 로더를 개발합니다.
먼저 모듈 콘텐츠를 로드하는 함수를 작성하고 이 함수를 비공개 범위로 래핑한 다음 eval()을 통해 평가하여 함수를 실행합니다.
function loadModule(파일 이름, 모듈, 요구 사항) { const WrappedSrc = `(함수(모듈, 내보내기, 요구) { ${fs.readFileSync(파일 이름, 'utf8)} }(모듈, module.exports, 요구)` 평가(래핑된Src) }
[모듈 공개]와 마찬가지로 모듈의 소스 코드가 함수로 래핑됩니다. 차이점은 일련의 변수(module, module.exports, require)도 함수에 전달된다는 점입니다.
모듈 내용은 [readFileSync]를 통해 읽혀진다는 점에 주목할 필요가 있습니다. 일반적으로 파일 시스템과 관련된 API를 호출할 때는 동기화된 버전을 사용하면 안 됩니다. 그러나 이번에는 다릅니다. CommonJs 시스템 자체를 통해 모듈을 로드하는 것은 여러 모듈이 올바른 종속성 순서로 도입될 수 있도록 동기 작업으로 구현되어야 하기 때문입니다.
그런 다음 모듈을 로드하는 것이 주요 기능인 require() 함수를 시뮬레이션합니다.
함수 요구(모듈 이름) { const id = require.resolve(모듈 이름) if (require.cache[id]) { require.cache[id].exports 반환 } // 모듈 메타데이터 const module = { 내보내기: {}, ID } //캐시 업데이트 require.cache[id] = 모듈 //모듈 로드 loadModule(id, module, require) // 내보낸 변수를 반환합니다. return module.exports } require.cache = {} require.resolve = (moduleName) => { // moduleName을 기반으로 전체 모듈 ID를 구문 분석합니다. }
(1) 함수는 moduleName을 받은 후 먼저 모듈의 전체 경로를 구문 분석하고 이를 ID에 할당합니다.
(2) cache[id]
가 true이면 모듈이 로드되었음을 의미하며 캐시 결과가 직접 반환됩니다. (3) 그렇지 않으면 첫 번째 로딩을 위한 환경이 구성됩니다. 구체적으로, 내보내기(즉, 내보낸 콘텐츠) 및 ID(함수는 위와 같음)를 포함하는 모듈 개체를 만듭니다.
(4) 처음 로드된 모듈을 캐시합니다. (5) loadModule을 통해 모듈의 소스 파일에서 소스 코드를 읽습니다. (6) 마지막으로 return module.exports
내보내려는 콘텐츠를 반환합니다.
require 함수를 시뮬레이션할 때 매우 중요한 세부 사항이 있습니다. require 함수는 동기식이어야 합니다 . 그 기능은 모듈 내용을 직접 반환하는 것뿐이며 콜백 메커니즘을 사용하지 않습니다. Node.js의 require도 마찬가지입니다. 따라서 module.exports에 대한 할당 작업도 동기식이어야 합니다. 비동기식을 사용하면 문제가 발생합니다.
// 문제가 발생했습니다. setTimeout(() => { module.exports = 함수 () {} }, 1000)
require가 동기 함수라는 사실은 모듈을 정의하는 방법에 매우 중요한 영향을 미칩니다. 왜냐하면 모듈을 정의할 때 동기 코드만 사용하도록 강제하므로 Node.js는 이 목적을 위해 대부분의 비동기 API의 동기 버전을 제공하기 때문입니다.
초기 Node.js에는 require 함수의 비동기 버전이 있었지만 함수가 매우 복잡해지기 때문에 빠르게 제거되었습니다.
ESM은 다양한 실행 환경에 적응하기 위해 JavaScript 언어의 공식 모듈 시스템을 지정하는 ECMAScript2015 사양의 일부입니다.
기본적으로 Node.js는 .js 접미사가 있는 파일을 CommonJS 구문을 사용하여 작성된 것으로 처리합니다. .js 파일에서 직접 ESM 구문을 사용하는 경우 인터프리터가 오류를 보고합니다.
Node.js 인터프리터를 ESM 구문으로 변환하는 방법에는 세 가지가 있습니다.
1. 파일 확장자를 .mjs로 변경합니다.
2. "module" 값을 사용하여 최신 package.json 파일에 유형 필드를 추가합니다.
3. 문자열은 매개변수로 --eval
에 전달되거나 --input-type=module
플래그와 함께 STDIN 파이프를 통해 노드로 전송됩니다.
예를 들어:
node --input-type=module --eval "'node:path'에서 { sep } 가져오기; console.log(9월);"
ESM은 URL로 구문 분석되고 캐시될 수 있습니다. 이는 특수 문자가 백분율로 인코딩되어야 함을 의미합니다. file:
node:
및 data:
파일:URL
모듈을 확인하는 데 사용된 가져오기 지정자에 다른 쿼리나 조각이 있는 경우 모듈이 여러 번 로드됩니다.
// 두 개의 서로 다른 모듈로 간주 import './foo.mjs?query=1'; import './foo.mjs?query=2';
데이터:URL
MIME 유형을 사용한 가져오기 지원:
ES 모듈용 text/javascript
JSON용 application/json
Wasm용 application/wasm
import 'data:text/javascript,console.log("hello!");'; import _ from 'data:application/json,"world!"' 주장 { type: 'json' };
data:URL
내장 모듈에 대한 기본 및 절대 지정자만 구문 분석합니다. data:
는 특수 프로토콜이 아니며 상대 구문 분석 개념이 없기 때문에 상대 지정자를 구문 분석하는 것은 작동하지 않습니다.
Import Assertion <br/>이 속성은 모듈 import 문에 인라인 구문을 추가하여 모듈 지정자 옆에 더 많은 정보를 전달합니다.
import fooData from './foo.json' 주장 { 유형: 'json' }; const { 기본값: barData } = import import('./bar.json', { 주장: { 유형: 'json' } });
현재는 JSON 모듈만 지원되며, assert { type: 'json' }
구문은 필수입니다.
Wash 모듈 가져오기 <br/>WebAssembly 모듈 가져오기는 --experimental-wasm-modules
플래그에서 지원되므로 모든 .wasm 파일을 일반 모듈로 가져오는 동시에 해당 모듈 가져오기도 지원합니다.
// index.mjs *를 './module.wasm'에서 M으로 가져옵니다. console.log(M)
실행하려면 다음 명령을 사용하십시오.
노드 --실험-wasm-모듈 index.mjs
Wait 키워드는 ESM의 최상위 수준에서 사용할 수 있습니다.
// a.mjs const 5 내보내기 = Promise.resolve(5) 대기 // b.mjs './a.mjs'에서 { 5개 } 가져오기 console.log(5) // 5
앞서 언급했듯이 import 문의 모듈 종속성 해결은 정적이므로 다음과 같은 두 가지 유명한 제한 사항이 있습니다.
모듈 식별자는 런타임이 생성될 때까지 기다릴 수 없습니다.
모듈 import 문은 파일 상단에 작성해야 하며 제어 흐름 문에 중첩될 수 없습니다.
그러나 일부 상황에서는 이 두 가지 제한 사항이 의심할 여지 없이 너무 엄격합니다. 예를 들어, 비교적 일반적인 요구사항이 있습니다: 지연 로딩 :
큰 모듈을 접할 때, 모듈의 특정 기능을 실제로 사용해야 할 때만 이 거대한 모듈을 로드하고 싶을 것입니다.
이를 위해 ESM은 비동기식 도입 메커니즘을 제공합니다. 이 소개 작업은 프로그램이 실행 중일 때 import()
연산자를 통해 수행될 수 있습니다. 구문적 관점에서 보면 모듈 식별자를 매개변수로 받고 Promise를 반환하는 함수와 동일합니다. Promise가 해결되면 구문 분석된 모듈 객체를 얻을 수 있습니다.
순환 종속성의 예를 사용하여 ESM 로드 프로세스를 설명합니다.
// index.js *를 './foo.js'에서 foo로 가져옵니다. *를 './bar.js'에서 막대로 가져옵니다. console.log(foo); console.log(bar); // foo.js *를 './bar.js'에서 Bar로 가져오기 내보내기 로드됨 = false; const bar = Bar 내보내기; 로드 = 사실; //bar.js *를 './foo.js'에서 Foo로 가져옵니다. 내보내기 로드됨 = false; 수출 const foo = Foo; 로드됨 = 사실
먼저 실행 결과를 살펴보겠습니다.
load를 통해 foo와 bar 모듈 모두 로드된 전체 모듈 정보를 기록할 수 있다는 것을 확인할 수 있습니다. 하지만 CommonJS는 완전히 로드된 후의 모습을 인쇄할 수 없는 모듈이 있어야 합니다.
이 결과가 발생하는 이유를 알아보기 위해 로딩 프로세스를 자세히 살펴보겠습니다.
로딩 프로세스는 세 단계로 나눌 수 있습니다.
첫 번째 단계: 분석
두 번째 단계: 선언
세 번째 단계: 실행
구문 분석 단계:
인터프리터는 항목 파일(즉, index.js)에서 시작하여 모듈 간의 종속성을 분석하고 이를 그래프 형태로 표시합니다. 이 그래프를 종속성 그래프라고도 합니다.
이 단계에서는 import 문에만 집중하고 이러한 문이 소개하려는 모듈에 해당하는 소스 코드를 로드합니다. 그리고 심층 분석을 통해 최종 종속성 그래프를 얻습니다. 위의 예를 들어 설명하십시오.
1. index.js부터 시작하여 import * as foo from './foo.js'
찾아 foo.js 파일로 이동합니다.
2. foo.js 파일에서 계속 구문 분석하고 import * as Bar from './bar.js'
문을 찾아서 bar.js로 이동합니다.
3. bar.js에서 계속 구문 분석하고 순환 종속성을 형성하는 import * as Foo from './foo.js'
찾습니다. 그러나 인터프리터가 이미 foo.js 모듈을 처리하고 있으므로 입력하지 않습니다. 다시 한 번 실행한 다음 bar 모듈을 구문 분석하세요.
4. bar 모듈을 파싱한 결과 import 문이 없는 것을 발견하여 foo.js로 반환하여 파싱을 계속합니다. import 문을 끝까지 다시 찾지 못하고 index.js가 반환되었습니다.
5. import * as bar from './bar.js'
는 index.js에 있지만 bar.js는 이미 파싱되었으므로 건너뛰고 계속 실행합니다.
마지막으로 깊이 우선 접근 방식을 통해 종속성 그래프가 완전히 표시됩니다.
선언 단계:
인터프리터는 획득한 종속성 그래프에서 시작하여 아래에서 위로 순서대로 각 모듈을 선언합니다. 특히 모듈에 도달할 때마다 모듈에서 내보낼 모든 속성을 검색하고 내보낸 값의 식별자를 메모리에 선언합니다. 이 단계에서는 선언만 이루어지며 할당 작업은 수행되지 않습니다.
1. 인터프리터는 bar.js 모듈에서 시작하여 로드된 식별자와 foo를 선언합니다.
2. foo.js 모듈까지 추적하고 로드된 식별자와 bar 식별자를 선언합니다.
3. index.js 모듈에 도착했지만 이 모듈에는 내보내기 문이 없으므로 식별자가 선언되지 않았습니다.
모든 내보내기 식별자를 선언한 후 종속성 그래프를 다시 살펴보고 가져오기와 내보내기 간의 관계를 연결하세요.
가져오기에 의해 도입된 모듈과 내보내기에 의해 내보낸 값 사이에 const와 유사한 바인딩 관계가 설정되는 것을 볼 수 있습니다. 게다가 index.js에서 읽은 bar 모듈과 foo.js에서 읽은 bar 모듈은 본질적으로 동일한 인스턴스입니다.
이것이 바로 이 예제의 결과에 완전한 구문 분석 결과가 출력되는 이유입니다.
이는 CommonJS 시스템에서 사용되는 접근 방식과 근본적으로 다릅니다. 모듈이 CommonJS 모듈을 가져오는 경우 시스템은 후자의 전체 내보내기 개체를 복사하고 해당 내용을 현재 모듈에 복사합니다. 이 경우 가져온 모듈이 자체 복사 변수를 수정하면 사용자는 새 값을 볼 수 없습니다. .
실행 단계:
이 단계에서 엔진은 모듈의 코드를 실행합니다. 종속성 그래프는 여전히 상향식으로 액세스되며 액세스된 파일은 하나씩 실행됩니다. 실행은 bar.js 파일에서 시작하여 foo.js로, 마지막으로 index.js로 시작됩니다. 이 과정에서 내보내기 테이블의 식별자 값이 점차 향상됩니다.
이 과정은 CommonJS와 크게 다르지 않은 것 같지만 실제로는 큰 차이가 있습니다. CommonJS는 동적이기 때문에 관련 파일을 실행하는 동안 종속성 그래프를 구문 분석합니다. 따라서 require 문이 표시되는 한 프로그램이 이 문에 도달할 때 이전 코드가 모두 실행되었음을 확신할 수 있습니다. 따라서 require 문은 반드시 파일 시작 부분에 나타날 필요는 없지만 어디에나 나타날 수 있으며 모듈 식별자는 변수에서 구성될 수도 있습니다.
그러나 ESM은 다릅니다. ESM에서는 위의 세 단계가 서로 분리되어 있으므로 코드를 실행하기 전에 먼저 종속성 그래프를 완전히 구성해야 합니다. 따라서 모듈을 내보내는 작업은 정적이어야 합니다. 코드가 실행될 때까지 기다리지 마십시오.
앞서 언급한 몇 가지 차이점 외에도 주목할 만한 몇 가지 차이점이 있습니다.
ESM에서 import 키워드를 사용하여 상대 또는 절대 지정자를 확인하는 경우 파일 확장자를 제공해야 하며 디렉터리 인덱스('./path/index.js')를 완전히 지정해야 합니다. CommonJS require 함수를 사용하면 이 확장을 생략할 수 있습니다.
ESM은 기본적으로 엄격 모드에서 실행되며 이 엄격 모드는 비활성화할 수 없습니다. 따라서 선언되지 않은 변수를 사용할 수 없으며, 엄격하지 않은 모드(예: with)에서만 사용할 수 있는 기능도 사용할 수 없습니다.
CommonJS는 일부 전역 변수를 제공합니다. 이러한 변수는 ESM에서 사용할 수 없습니다. 이러한 변수를 사용하려고 하면 ReferenceError가 발생합니다. 포함하다
require
exports
module.exports
__filename
__dirname
이 중 __filename
현재 모듈 파일의 절대 경로를 의미하고, __dirname
파일이 위치한 폴더의 절대 경로를 의미합니다. 이 두 변수는 현재 파일의 상대 경로를 구성할 때 매우 유용하므로 ESM은 두 변수의 기능을 구현하는 몇 가지 방법을 제공합니다.
ESM에서는 import.meta
객체를 사용하여 현재 파일의 URL을 참조하는 참조를 얻을 수 있습니다. 구체적으로 현재 모듈의 파일 경로는 import.meta.url
통해 얻습니다. 이 경로의 형식은 file:///path/to/current_module.js
와 유사합니다. 이 경로를 기반으로 __filename
및 __dirname
으로 표현되는 절대 경로가 구성됩니다.
'url'에서 { fileURLToPath } 가져오기 '경로'에서 { dirname } 가져오기 const __filename = fileURLToPath(import.meta.url) const __dirname = 디렉토리명(__파일명)
CommonJS에서 require() 함수를 시뮬레이션할 수도 있습니다.
'모듈'에서 { createRequire } 가져오기 const require = createRequire(import.meta.url)
ESM 전역 범위에서는 정의되지 않았지만 CommonJS 모듈 시스템에서는 내보내기에 대한 참조입니다.
//ESM console.log(this) // 정의되지 않음 // 커먼JS console.log(this === 내보내기) // true
위에서 언급한 것처럼 CommonJS require() 함수는 CommonJS 모듈을 로드하기 위해 ESM에서 시뮬레이션될 수 있습니다. 또한 표준 가져오기 구문을 사용하여 CommonJS 모듈을 도입할 수도 있지만 이 가져오기 방법은 기본적으로 내보낸 항목만 가져올 수 있습니다.
import packageMain from 'commonjs-package' // 'commonjs-package'에서 { method }를 가져오는 것이 완전히 가능합니다. // 오류
CommonJS 모듈의 요구 사항은 항상 참조하는 파일을 CommonJS로 처리합니다. ES 모듈에는 비동기 실행이 있으므로 require를 사용하여 ES 모듈을 로드하는 것은 지원되지 않습니다. 그러나 import()
사용하여 CommonJS 모듈에서 ES 모듈을 로드할 수 있습니다.
ESM이 출시된 지 7년이 지났지만 node.js에서도 안정적으로 지원하고 있습니다. 우리가 컴포넌트 라이브러리를 개발할 때는 ESM만 지원할 수 있습니다. 하지만 기존 프로젝트와 호환되기 위해서는 CommonJS에 대한 지원도 필수적입니다. 구성 요소 라이브러리가 두 모듈 시스템 모두에서 내보내기를 지원하도록 만드는 데 널리 사용되는 두 가지 방법이 있습니다.
CommonJS에서 패키지를 작성하거나 ES 모듈 소스 코드를 CommonJS로 변환하고 명명된 내보내기를 정의하는 ES 모듈 래퍼 파일을 만듭니다. 조건부 내보내기를 사용하고 가져오기는 ES 모듈 래퍼를 사용하며 필수는 CommonJS 진입점을 사용합니다. 예를 들어, 예제 모듈에서
//패키지.json { "유형": "모듈", "내보내기": { "가져오기": "./wrapper.mjs", "require": "./index.cjs" } }
디스플레이 확장자 .cjs
및 .mjs
를 사용하세요. .js
만 사용하면 기본적으로 CommonJS로 설정되거나 "type": "module"
로 인해 이러한 파일이 ES 모듈로 처리되기 때문입니다.
// ./index.cjs 내보내기.이름 = '이름'; // ./wrapper.mjs './index.cjs'에서 cjsModule 가져오기 const 이름 내보내기 = cjsModule.name;
이 예에서는 다음과 같습니다.
// ESM을 사용하여 'example'에서 import { name }을 소개합니다. // CommonJS를 사용하여 const { name } = require('example')을 소개합니다.
두 가지 방법으로 모두 도입된 이름은 동일한 싱글톤입니다.
package.json 파일은 별도의 CommonJS 및 ES 모듈 진입점을 직접 정의할 수 있습니다.
//패키지.json { "유형": "모듈", "내보내기": { "가져오기": "./index.mjs", "require": "./index.cjs" } }
이는 패키지의 CommonJS 및 ESM 버전이 동일한 경우 수행할 수 있습니다. 예를 들어 하나는 다른 하나의 변환된 출력이고 패키지의 상태 관리는 신중하게 격리되어 있습니다(또는 패키지가 상태 비저장).
상태가 문제가 되는 이유는 패키지의 CommonJS 및 ESM 버전이 모두 애플리케이션에서 사용될 수 있기 때문입니다. 예를 들어 사용자의 리퍼러 코드는 ESM 버전을 가져올 수 있지만 종속성에는 CommonJS 버전이 필요합니다. 이런 일이 발생하면 패키지의 두 복사본이 메모리에 로드되므로 두 가지 다른 상태가 발생합니다. 이로 인해 해결하기 어려운 오류가 발생할 수 있습니다.
상태 비저장 패키지를 작성하는 것 외에도(예를 들어 JavaScript의 Math가 패키지인 경우 모든 메서드가 정적이므로 상태 비저장이 됩니다) 잠재적으로 로드된 CommonJS와 ESM에서 사용할 수 있도록 상태를 분리하는 방법이 있습니다. 패키지 인스턴스:
가능하다면 인스턴스화된 객체에 모든 상태를 포함하십시오. 예를 들어, JavaScript의 Date는 상태를 포함하기 위해 인스턴스화되어야 합니다. 패키지인 경우 다음과 같이 사용됩니다.
'날짜'에서 날짜를 가져옵니다. const someDate = 새로운 날짜(); // someDate에는 상태가 포함되어 있지만 Date에는 상태가 포함되어 있지 않습니다.
new 키워드는 필요하지 않습니다. 패키지 함수는 새 객체를 반환하거나 전달된 객체를 수정하여 패키지 외부의 상태를 유지할 수 있습니다.
패키지의 CommonJS와 ESM 버전 간에 공유되는 하나 이상의 CommonJS 파일에서 상태를 분리합니다. 예를 들어 CommonJS 및 ESM의 진입점은 각각 index.cjs 및 index.mjs입니다.
// index.cjs const 상태 = require('./state.cjs') module.exports.state = 상태; // index.mjs './state.cjs'에서 상태 가져오기 내보내다 { 상태 }
require 및 import를 통해 애플리케이션에서 예제가 사용되더라도 예제에 대한 모든 참조에는 동일한 상태가 포함되며 두 모듈 시스템의 상태 변경 사항은 둘 다에 적용됩니다.
이 글이 도움이 되셨다면 좋아요와 응원 부탁드립니다. 여러분의 '좋아요'는 제가 계속 창작을 할 수 있는 원동력이 됩니다.
이 기사에서는 다음 정보를 인용합니다.
node.js 공식 문서
Node.js 디자인 패턴