mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 09:25:54 +00:00
docs(esm): add notes about default exports (#2036)
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
parent
ac98373b4c
commit
be1d8ff005
@ -142,6 +142,68 @@ export default defineNuxtConfig({
|
||||
})
|
||||
```
|
||||
|
||||
### Default exports
|
||||
|
||||
A dependency with CommonJS format, can use `module.exports` or `exports` to provide a default export:
|
||||
|
||||
```js [node_modules/cjs-pkg/index.js]
|
||||
module.exports = { test: 123 }
|
||||
// or
|
||||
exports.test = 123
|
||||
```
|
||||
|
||||
This normally works well if we `require` such dependency:
|
||||
|
||||
```js [test.cjs]
|
||||
const pkg = require('cjs-pkg')
|
||||
|
||||
console.log(pkg) // { test: 123 }
|
||||
```
|
||||
|
||||
[Node.js in native ESM mode](https://nodejs.org/api/esm.html#interoperability-with-commonjs), [typescript with `esModuleInterop` enabled](https://www.typescriptlang.org/tsconfig#esModuleInterop) and bundlers such as Webpack, provide a compatibility mechanism so that we can default import such library.
|
||||
This mechanism is often referred to as "interop require default":
|
||||
|
||||
```js
|
||||
import pkg from 'cjs-pkg'
|
||||
|
||||
console.log(pkg) // { test: 123 }
|
||||
```
|
||||
|
||||
However, because of complexities for syntax detection and different bundle formats, there is always a chance that interop default fails and we end up with something like this:
|
||||
|
||||
```js
|
||||
import pkg from 'cjs-pkg'
|
||||
|
||||
console.log(pkg) // { default: { test: 123 } }
|
||||
```
|
||||
|
||||
Also when using dynamic import syntax (in both CJS and ESM files), we always have this situation:
|
||||
|
||||
```js
|
||||
import('cjs-pkg').then(console.log) // [Module: null prototype] { default: { test: '123' } }
|
||||
```
|
||||
|
||||
In this case, we need to manually inerop default export:
|
||||
|
||||
```js
|
||||
// Static import
|
||||
import { default as pkg } from 'cjs-pkg'
|
||||
|
||||
// Dynamic import
|
||||
import('cjs-pkg').then(m => m.default || m).then(console.log)
|
||||
```
|
||||
|
||||
For handling more complex situations and more safety, we recommand and internally use [mlly](https://github.com/unjs/mlly) in Nuxt 3 that can preserve named exports.
|
||||
|
||||
```js
|
||||
import { interopDefault } from 'mlly'
|
||||
|
||||
// Assuming the shape is { default: { foo: 'bar' }, baz: 'qux' }
|
||||
import myModule from 'my-module'
|
||||
|
||||
console.log(interopDefault(myModule)) // { foo: 'bar', baz: 'qux' }
|
||||
```
|
||||
|
||||
## Library author guide
|
||||
|
||||
The good news is that it's relatively simple to fix issues of ESM compatibility. There are really two main options:
|
||||
@ -228,7 +290,7 @@ const someFile = await resolvePath('my-lib', { url: import.meta.url })
|
||||
|
||||
### Best practices
|
||||
|
||||
- Prefer named exports rather than default export. This helps reduce CJS conflicts.
|
||||
- Prefer named exports rather than default export. This helps reduce CJS conflicts. (see [Default exports](#default-exports) section)
|
||||
|
||||
- Avoid depending on Node.js built-ins and CommonJS or Node.js-only dependencies as much as possible to make your library usable in Browsers and Edge Workers without needing Nitro polyfills.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user