Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Real ESM support #193

Closed
samhh opened this issue Jun 30, 2023 · 9 comments
Closed

Real ESM support #193

samhh opened this issue Jun 30, 2023 · 9 comments
Labels

Comments

@samhh
Copy link
Owner

samhh commented Jun 30, 2023

In a fully ESM project:

import { sum } from "fp-ts-std/Array";
         ^^^
SyntaxError: Named export 'sum' not found. The requested module 'fp-ts-std/Array' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'fp-ts-std/Array';
const { sum } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)

Node.js v18.16.0

And then with that change:

(node:55013) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/path/to/repo/.yarn/__virtual__/fp-ts-std-virtual-e76da617af/4/.yarn/berry/cache/fp-ts-std-npm-0.17.1-8c0fa4fe44-8.zip/node_modules/fp-ts-std/dist/esm/Array.js:1
import { constant, pipe, flow, flip } from "fp-ts/function";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1176:20)
    at Module._compile (node:internal/modules/cjs/loader:1218:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at require$$0.Module._extensions..js (/path/to/repo/.pnp.cjs:9101:33)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at require$$0.Module._load (/path/to/repo/.pnp.cjs:8920:22)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Node.js v18.16.0

Related: #113

@samhh
Copy link
Owner Author

samhh commented Jun 30, 2023

Should be resolved in the esm branch, however that's blocked by docs-ts: gcanti/docs-ts#59 (comment)

@samhh
Copy link
Owner Author

samhh commented Jun 30, 2023

Actually in different projects I'm seeing different results. One works, the other complains about the fp-ts imports. 😒

@samhh samhh changed the title Iffy ESM Real ESM support Jun 30, 2023
@samhh
Copy link
Owner Author

samhh commented Jul 4, 2023

I think 0.18.0-beta.3 is the first to work fully with both proper ESM and CJS.

Depending on the consuming project different packaging issues can surface, most of which don't reveal themselves when building here.

The latest surprise is that tsc requires the consuming project to be ESM to read a package's exports field, hence the return of the typesVersions hack.

@samhh
Copy link
Owner Author

samhh commented Jul 4, 2023

Nope, spoke too soon, the fp-ts imports need updating. 😡

@samhh
Copy link
Owner Author

samhh commented Jul 4, 2023

Webpack:

ERROR in ./node_modules/fp-ts-std/dist/esm/URL.js 2:0-34
Module not found: Error: Can't resolve 'fp-ts/Either' in '/path/to/repo/node_modules/fp-ts-std/dist/esm'
Did you mean 'Either.js'?
BREAKING CHANGE: The request 'fp-ts/Either' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

Similar in a Node REPL:

> await import('fp-ts-std/Array')
Uncaught:
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/path/to/repo/node_modules/fp-ts/function' is not supported resolving ES modules imported from /path/to/repo/node_modules/fp-ts-std/dist/esm/Array.js
Did you mean to import fp-ts/lib/function.js?
    at new NodeError (node:internal/errors:399:5)
    at finalizeResolution (node:internal/modules/esm/resolve:319:17)
    at moduleResolve (node:internal/modules/esm/resolve:945:10)
    at defaultResolve (node:internal/modules/esm/resolve:1153:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///path/to/repo/node_modules/fp-ts/function'
}

From debugging in the REPL it looks like the imports need to be from lib, not es6.

@samhh
Copy link
Owner Author

samhh commented Jul 4, 2023

^ Fixed in 0.18.0-beta.4, however there's been some significant bundle bloat in a CJS project.

@samhh
Copy link
Owner Author

samhh commented Jul 5, 2023

I'm interpreting this to mean that fp-ts-std effectively can't be ESM until fp-ts et al are.

Perhaps the bundle bloat could be resolved with some clever bundler.

@samhh samhh added the blocked label Jul 5, 2023
@samhh
Copy link
Owner Author

samhh commented Jul 5, 2023

The bundle bloat mostly goes away if the bundler is configured to rewrite fp-ts/lib imports to fp-ts/es6 (e.g. Webpack's resolve.alias). It doesn't entirely solve it however, and expecting non-ESM bundle-sensitive consumers to do this is a big ask.

@samhh
Copy link
Owner Author

samhh commented Nov 6, 2023

The status quo makes the package effectively entirely broken for ESM projects as the subpath exports prevent you from manually importing from /cjs. Curiously if you import a CJS module which in turn imports fp-ts-std it resolves correctly.

@samhh samhh closed this as not planned Won't fix, can't repro, duplicate, stale Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant