remix-run / history

Manage session history with JavaScript
MIT License
8.29k stars 961 forks source link

Named exports don’t work with Node.js ESM support #927

Open calebmer opened 2 years ago

calebmer commented 2 years ago

When you try to import {createMemoryHistory} from 'history' in a Node.js .mjs file you get an error that createMemoryHistory is not a named export.

It appears that this is because the only main field supported by Node.js history exposes is "main" which points to a CommonJS module with exports that can’t be inferred by cjs-module-lexer. I think "exports" is the new field Node.js uses to lookup compatible ES Modules.

https://github.com/remix-run/history/blob/8117ab21f5e339fabaa6ed1d80290fe3cee40c27/packages/history/package.json#L8-L11

zvictor commented 2 years ago

I don't understand how the package.json has been designed. How is it possible that there is no "type": "module", no "exports", no .mjs extension, but files like browser.js contain ESM code? How is the node client supposed to know that that file is ESM and not CJS?

The way package.json currently is, index.js is the only file that could contain ESM code because of the "main" entry. Did I get anything wrong here?


Lines like this one

import history from 'history/browser'

Throw error like these:

error - ~/myApp/node_modules/.pnpm/history@5.3.0/node_modules/history/browser.js:397
export { browser as default };
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1049:15)
    at Module._compile (node:internal/modules/cjs/loader:1084:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1174:10)
    at Module.load (node:internal/modules/cjs/loader:998:32)
    at Module._load (node:internal/modules/cjs/loader:839:12)
    at Module.require (node:internal/modules/cjs/loader:1022:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at history/browser (~/myApp/apps/jobs/.next/server/pages/index.js:2144:18)
    at __webpack_require__ (~/myApp/apps/jobs/.next/server/webpack-runtime.js:33:43) {
  page: '/'
}