网页
综合
更新时间 2026-11-14 16:18:45
ECMAScript Modules | Webpack
自动蜘蛛
webpack.kr
正文约 4442 字
ECMAScript 모듈(ESM)은 웹에서 모듈을 사용하기 위한 사양입니다. 모든 최신 브라우저와 권장하는 웹 모듈 코드 작성법에서 지원됩니다.
Webpack은 ECMAScript 모듈을 최적화하기 위한 처리를 지원합니다.
export 키워드를 사용하면 ESM 항목을 다른 모듈에 노출할 수 있습니다.
import 키워드를 사용하면 다른 모듈에 대한 참조를 ESM으로 가져올 수 있습니다.
ECMAScript 모듈에서 namespace 객체를 가져오면 webpack은 ESM 규칙에 따라 namespace 객체의 Symbol.toStringTag를 "Module"로 설정합니다.
기본적으로 webpack은 파일이 ESM인지 또는 다른 모듈 시스템인지 자동으로 감지합니다.
Node.js는 package.json의 속성을 사용하여 파일의 모듈 유형을 명시적으로 설정하는 방법을 확립했습니다. package.json에서 "type": "module"을 설정하면 package.json 아래의 모든 파일이 ECMAScript 모듈이 됩니다. "type": "commonjs"를 설정하면 CommonJS 모듈이 됩니다.
또한, 파일은 .mjs 또는 .cjs 확장자를 사용해서 모듈 유형을 설정할 수 있습니다. .mjs는 ESM이 되도록 강제하고, .cjs는 CommonJS가 되도록 강제합니다.
DataURIs에서 text/javascript 또는 application/javascript mime 유형을 사용하면 모듈 유형도 ESM으로 강제로 적용됩니다.
모듈 형식뿐 아니라 모듈 플래그를 ESM으로 지정하는 것은 로직 해석, interop 로직 및 모듈에서 사용 가능한 심볼에 영향을 줍니다.
Webpack은 ESM에서 사용할 수 있는 여러 import.meta 속성을 제공합니다.
예시 - 에셋에 import.meta.url 사용하기:
예시 - ESM에서 HMR 사용하기:
ESM에서는 모듈 최상위 레벨에서 await를 사용할 수 있습니다. Webpack은 해당 모듈을 자동으로 비동기 모듈로 처리합니다. 이 기능은 5.83.0부터 기본 활성화되었고, experiments.topLevelAwait 옵션 자체는 5.102.0에서 제거되었습니다. 즉, 별도 설정 없이 동작합니다.
브라우저를 대상으로 할 때는 엔트리 포인트에서 top-level await 사용을 피하세요. 전체 모듈 그래프의 평가가 지연됩니다. 지연 로딩이 필요하다면 import()를 사용하는 편이 좋습니다. Node.js, Electron, Web Worker 대상에서는 이 제한이 적용되지 않습니다.
ESM의 import는 더 엄격하게 해석됩니다. 파일이 ESM으로 지정된 경우, Node.js 규칙에 따라 상대 경로 요청에는 파일 확장자(예: *.js, *.mjs)를 포함해야 합니다.
import "lodash" 같이 패키지에 대한 요청은 여전히 지원됩니다.
대규모 CJS 코드베이스를 마이그레이션할 때처럼 이 검사를 비활성화해야 한다면 fullySpecified=false를 사용할 수 있습니다.
ESM에서는 require, module, exports, __filename, __dirname 같은 CommonJS 구문을 사용할 수 없습니다.
webpack이 ESM에서 import된 CommonJS 모듈을 번들할 때, default import(전체 module.exports 객체)와 named import(해당 속성들) 모두 동작합니다.
이 상호 운용성은 webpack이 import된 모듈을 CommonJS로 처리할 때 적용됩니다. 해당 모듈 자체가 ESM export 구문을 사용하면 webpack이 이를 자동으로 ESM으로 감지하여 export를 직접 사용합니다. 이는 "type": "module"이 설정된 프로젝트에서 .js 파일을 혼용할 때 자주 나타납니다. 프로젝트 내부 일부 파일은 ESM으로 처리되는 반면, node_modules의 서드파티 패키지는 여전히 CommonJS인 경우가 많기 때문입니다.
이것은 webpack의 번들링 동작입니다. Node.js 자체가 ESM에서 CommonJS 모듈을 로드할 때, named import는 Node.js가 정적으로 감지할 수 있는 경우에만 동작합니다. 그렇지 않으면 default import만 사용할 수 있습니다. ESM으로 마이그레이션하거나 @babel/plugin-transform-modules-commonjs 사용을 고려하세요.
webpack은 디펜던시 코드를 찾은 그대로 번들합니다. target과 browserslist 설정은 webpack이 생성하는 런타임 코드를 제한하며, 사용자나 패키지가 작성한 문법을 다운레벨하지 않습니다. 따라서 화살표 함수, optional chaining, 클래스 필드로 게시된 패키지는 게시된 그대로 브라우저에 도달하며, 구형 브라우저는 패키지가 아닌 번들을 가리키는 오류와 함께 파싱 시점에 실패합니다.
이는 exports 필드를 리졸브하는 webpack 5와 함께 더 일반적이 되었습니다. 레거시 빌드와 모던 빌드를 모두 제공하는 패키지는 이제 기본적으로 webpack에 모던 빌드를 전달합니다.
해결 방법은 두 가지이며, 상호 배타적이지 않습니다.
디펜던시를 트랜스파일합니다. 이 사이트의 빌드 성능 페이지를 포함한 가이드들은 node_modules에서 로더를 제외하도록 권장합니다. 이것은 코드의 대부분이고 변환하는 데 가장 느린 부분이므로 올바른 기본값입니다. 그 규칙을 제거하는 대신, 필요한 패키지만 예외로 추가하세요.
조건 문법은 이것을 반대 방향으로도 표현할 수 있습니다. exclude: { and: [/node_modules/], not: [/node_modules[\\/]pkg-a[\\/]/] }는 하나의 패키지를 제외하고 node_modules를 건너뜁니다.
CommonJS와 ESM을 혼합한 파일이 있는 패키지는 Babel 옵션에서 sourceType: "unambiguous"가 필요합니다. 그렇지 않으면 Babel이 모든 파일을 하나 또는 다른 것으로 처리하고 잘못된 절반이 깨집니다.
또는 다른 빌드를 리졸브합니다. 패키지가 다른 조건이나 필드 아래 ES5 번들을 여전히 게시하고 있다면, 트랜스파일하는 대신 webpack이 그것을 가리키도록 하세요. resolve.conditionNames와 resolve.mainFields를 참조하세요. 두 가지 모두 webpack이 리졸브하는 모든 패키지에 적용되므로, 전역적으로 변경하는 대신 resolve.byDependency나 패키지별 Rule.resolve로 범위를 좁히세요.
어떤 방법을 선택하든 webpack이 자체 런타임을 위해 내보내는 문법은 별도의 설정입니다. browserslist 설정을 유지하거나 target을 ['web', 'es5']와 같이 설정하여 런타임이 동일한 브라우저에서 실패하지 않도록 하세요.
ReferenceError: require is not defined
파일이 ESM으로 처리되면 CommonJS 전역 객체인 require, module, exports, __filename, __dirname를 사용할 수 없습니다.
해결: require()를 import 구문으로 바꾸세요. 조건부 또는 동적 로딩이 필요하다면 import()를 사용하세요.
Must use import to load ES Module (Node.js) / SyntaxError: Cannot use import statement in a module (browser)
이 오류는 ESM import/export 구문을 사용하는 파일이 ESM으로 지정되지 않았을 때 발생합니다. package.json에 "type": "module"이 없거나, 파일 확장자가 .mjs가 아니라 .js인 경우가 대표적입니다.
해결: package.json에 "type": "module"을 추가하거나 파일 확장자를 .mjs로 변경하세요.
Module not found: Error: Can't resolve './utils' (missing extension)
ESM에서는 상대 import에 파일 확장자를 포함해야 합니다. Webpack도 여기서는 Node.js의 ESM 규칙을 따릅니다.
해결: import { helper } from './utils'를 import { helper } from './utils.js'로 바꾸거나, 마이그레이션하는 동안에는 webpack 설정에서 fullySpecified: false를 지정해 이 검사를 끌 수 있습니다.
저작권은 OpenJS Foundation 및 webpack 기여자에게 있으며, 모든 권리는 보호됩니다. OpenJS Foundation은 등록 상표를 보유하고 있으며 상표를 사용합니다. OpenJS Foundation의 상표 목록은 Trademark Policy와 Trademark List에서 확인할 수 있습니다. OpenJS Foundation 상표 목록에 표시되지 않은 상표 및 로고는 각 소유자의 상표™ 또는 등록 상표®입니다. 이를 사용한다고 해서 해당 소유자와의 제휴 관계나 보증을 의미하지는 않습니다.
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。