lukeed / sirv

An optimized middleware & CLI application for serving static files~!
MIT License
1.06k stars 56 forks source link

ESM import error #114

Closed btakita closed 2 years ago

btakita commented 3 years ago
import * as sirv_o from 'sirv'
const { default: sirv } = sirv_o

Results with the error:

'default' is not exported by ../../node_modules/.pnpm/mime@2.5.2/node_modules/mime/lite.js, imported by ../../node_modules/.pnpm/sirv@1.0.12/node_modules/sirv/build.mjs
3: import { parse } from '@polka/url';
4: import list from 'totalist/sync';
5: import mime from 'mime/lite';
lukeed commented 3 years ago

import * as imports as an object.

This module does not have native ESM enabled, so unless you're bundling, you'll be using the CommonJS entry.

Even so, this is the correct format. It will always worked and I just verified locally as well:

import sirv from 'sirv';

Your TS will be pissed off, but it'll be correct.

The format you used should only be used when you have multiple named imports, or if you have a default with named exports.

btakita commented 3 years ago

Not using TS. Thas was from a *.mjs file in a rollup build without @rollup/common-js-plugin. I'm not using @rollup/common-js-plugin since it does not seem to work with @swc/core

lukeed commented 3 years ago

I just reread the error message, sorry

My mime import is incorrect. It needs to be import * as while yours needs to be import sirv :D

I'll fix this tomorrow morning and publish a new patch.

Just mentioned TS for potential type checking errors.

btakita commented 3 years ago

Thank you...I think I was having this sort of issue with a few of your packages. I'll be more diligent about error reporting if I come across any issue as I have more time now. And as you said, import sirv from 'sirv' is better form in this case & has the same behavior.

lukeed commented 3 years ago

Hey, so I'm sorry to say, you 100% have something else going on.

With the currently released sirv version, I've verified that there's zero issue with native ESM usage. Even with the mime/lite import statement, Node natively resolves everything correctly:

// package.json
{
  "type": "module",
  "devDependencies": {
    "sirv": "1.0.12"
  }
}
// usage.js
import sirv from 'sirv';
import { createServer } from "http";

const assets = sirv('node_modules/sirv');
createServer(assets).listen(3000);
$ node usage.js

Then a GET to localhost:3000/license works as expected. No errors anywhere.

The same thing happens if I remove type: "module" and rename usage.js to usage.mjs. Zero errors, all works as expected.

I'm using Node 14.15.3, but I tested Node 12.18.3 and Node 16.2.0

lukeed commented 3 years ago

If, however, your sirv import is actually a sirv/build.mjs import, then yes, you will get errors.

This is expected & works as (Node) designed, since mime/lite and totalist/sync do not have those "module entry files" defined as exports. While I obviously control totalist and could take care of that, changes to mime would need to make changes to support native ESM too

But, as seen from my above example, none of this is needed. Node ESM is able to follow the dependency resolutions correctly even though/if they happen to be loading CommonJS code. If Node were not able to do this, native ESM would be dead on arrival since module interop would be impossible. (This was momentarily true, and was quickly fixed)

lukeed commented 2 years ago

The mime issue is resolved via d93f33f

sirv@2.0 will support native ESM usage.

lukeed commented 2 years ago

Closed via d93f33f and #86 Will be in next release.