You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/guides/ecma-script-modules.mdx
+136-4Lines changed: 136 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,7 @@ title: ECMAScript Modules
3
3
sort: 19
4
4
contributors:
5
5
- sokra
6
+
- ryzrr
6
7
related:
7
8
- title: ECMAScript Modules in Node.js
8
9
url: https://nodejs.org/api/esm.html
@@ -84,12 +85,143 @@ In DataURIs using the `text/javascript` or `application/javascript` mime type wi
84
85
85
86
In addition to the module format, flagging modules as ESM also affect the resolving logic, interop logic and the available symbols in modules.
86
87
87
-
Imports in ESM are resolved more strictly. Relative requests must include a filename and file extension (e.g. `*.js` or `*.mjs`) unless you have the behaviour disabled with [`fullySpecified=false`](/configuration/module/#resolvefullyspecified).
88
+
## import.meta in ESM
89
+
90
+
Webpack exposes several `import.meta` properties for use in ESM:
In ESM, you can use `await` at the top level of a module. Webpack treats the module
121
+
as an async module automatically. Enabled by default since 5.83.0; the `experiments.topLevelAwait` option itself was removed in 5.102.0 (it just works).
122
+
123
+
W> Avoid top-level await in your entry point when targeting the **browser**. It delays the entire module graph evaluation. Prefer `import()` for deferred loading. For Node.js, Electron, or Web Worker targets this restriction does not apply.
124
+
125
+
```js
126
+
// user.js (async ESM module)
127
+
constresponse=awaitfetch("/api/user");
128
+
exportconstuser=awaitresponse.json();
129
+
```
130
+
131
+
```js
132
+
// index.js - importing an async module works as expected
133
+
import { user } from"./user.js";
134
+
console.log(user.name);
135
+
```
136
+
137
+
## Fully Specified Imports
138
+
139
+
Imports in ESM are resolved more strictly. Relative requests must include a file extension (e.g. `*.js` or `*.mjs`) following the Node.js convention when the file is flagged as ESM:
140
+
141
+
```js
142
+
// correct in ESM
143
+
import { helper } from"./utils.js";
144
+
145
+
// will fail - missing extension
146
+
import { helper } from"./utils";
147
+
```
88
148
89
149
T> Requests to packages e.g. `import"lodash"` are still supported.
90
150
91
-
Only the "default" export can be imported from non-ESM. Named exports are not available.
151
+
To disable this check (useful when migrating a large CJS codebase), you can use [`fullySpecified=false`](/configuration/module/#resolvefullyspecified):
152
+
153
+
```js
154
+
// webpack.config.js
155
+
exportdefault {
156
+
module: {
157
+
rules: [
158
+
{
159
+
test:/\.m?js/,
160
+
resolve: {
161
+
fullySpecified:false,
162
+
},
163
+
},
164
+
],
165
+
},
166
+
};
167
+
```
168
+
169
+
## CommonJS Interop
170
+
171
+
CommonJS syntax is not available in ESM: `require`, `module`, `exports`, `__filename`, `__dirname`.
172
+
173
+
When importing from a CommonJS module inside ESM, only the `default` export
174
+
is available (the entire `module.exports` object):
175
+
176
+
```js
177
+
// cjs-module.js (CommonJS)
178
+
module.exports= { foo:1, bar:2 };
179
+
180
+
// esm-consumer.js (ESM)
181
+
importcjsfrom"./cjs-module.js";
182
+
console.log(cjs.foo); // works - cjs is the whole exports object
This happens when a file using ESM `import`/`export` syntax is not flagged as ESM -
213
+
either `"type": "module"` is missing from `package.json`, or the file uses a `.js`
214
+
extension instead of `.mjs`.
215
+
216
+
_Fix_: Add `"type": "module"` to your `package.json`, or rename the file to `.mjs`.
217
+
218
+
---
219
+
220
+
**`Module not found: Error: Can't resolve './utils'` (missing extension)**
92
221
93
-
CommonJs Syntax is not available: `require`, `module`, `exports`, `__filename`, `__dirname`.
222
+
In ESM, relative imports must include the file extension. Webpack follows the Node.js
223
+
ESM convention here.
94
224
95
-
T> HMR can be used with [`import.meta.webpackHot`](/api/module-variables/#importmetawebpackhot) instead of [`module.hot`](/api/module-variables/#modulehot-webpack-specific).
225
+
_Fix_: Change `import { helper } from './utils'` to `import { helper } from './utils.js'`,
226
+
or set [`fullySpecified: false`](/configuration/module/#resolvefullyspecified) in your
227
+
webpack config to disable the check while migrating.
0 commit comments