FredKSchott / snowpack

ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️
https://www.snowpack.dev
MIT License
19.48k stars 922 forks source link

[BUG] Default import is an ES module #3140

Closed fwouts closed 3 years ago

fwouts commented 3 years ago

Bug Report Quick Checklist

Describe the bug

An import statement such as import Head from "next/head" assigns Head the value {__esModule: true, defaultHead: function, default: function} instead of the expected function.

To Reproduce

  1. Clone https://github.com/fwouts/snowpack-next/tree/7e497046aea009b172a04bd0b479cf183a510cac
  2. Run yarn snowpack dev
  3. See error!
Screen Shot 2021-04-12 at 6 08 39 pm

Expected behavior

The expected behaviour can be experienced by running yarn dev, which runs this Next.js app with Webpack instead.

Anything else?

I investigated this, and found that it's caused by node_modules/next/head.js having the following code:

module.exports = require('./dist/next-server/lib/head')

The bug fixes itself if I replace it with:

export * from './dist/next-server/lib/head'
export { default } from './dist/next-server/lib/head'

I wonder if this could be an issue with Rollup?

drwpow commented 3 years ago

Unfortunately this is a casualty of CommonJS <-> ESM interop. From the TypeScript docs:

the ES6 modules spec states that a namespace import (import * as x) can only be an object, by having TypeScript treating it the same as = require("x") then TypeScript allowed for the import to be treated as a function and be callable. This breaks the spec’s recommendations.

So the .default is expected, is somewhat of a loose standard, and actually does solve a lot of problems. But it’s just something to expect whenever you try and import CommonJS code into ESM.