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

Fix import path in React.Basic.DOM.Server JS #38

Closed
wants to merge 1 commit into from

Conversation

kaol
Copy link

@kaol kaol commented Jun 15, 2022

The string in import statement in Server.js is a path and it requires the file suffix as well.

@pete-murphy
Copy link
Member

It does seem that the file extension is required here.

❯ spago repl                        
[1 of 1] Compiling React.Basic.DOM.Server
PSCi, version 0.15.0
Type :? for help

> import Prelude       
> import React.Basic.DOM.Server
> renderToString mempty
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/pete/Code/purescript/purescript-react-basic-dom/node_modules/react-dom/server' imported from /Users/pete/Code/purescript/purescript-react-basic-dom/.psci_modules/React.Basic.DOM.Server/foreign.js
Did you mean to import react-dom/server.js?
    at new NodeError (node:internal/errors:372:5)
    at finalizeResolution (node:internal/modules/esm/resolve:437:11)
    at moduleResolve (node:internal/modules/esm/resolve:1009:10)
    at defaultResolve (node:internal/modules/esm/resolve:1218:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:580:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:294:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
    at link (node:internal/modules/esm/module_job:78:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

After these changes, I see no errors

> :r                   
[1 of 1] Compiling React.Basic.DOM.Server
> renderToString mempty
""

@mjrussell
Copy link
Member

mjrussell commented Jun 16, 2022

Huh that's very weird. I can work on a hotfix release tomorrow. I'm only on my phone but any idea why this isn't being picked up by the GitHub actions?

@pete-murphy
Copy link
Member

pete-murphy commented Jun 16, 2022

I'm still not sure why this is, but it seems like there is a difference between how Node resolves CJS modules vs ESM modules:

According to the Node ESM docs

Including the file extension is only necessary for packages without an "exports" field.

So CommonJS import without extension succeeds

❯ echo "const { renderToString } = require('react-dom/server'); console.log(renderToString('example'))" | node
example

and ESM import with extension succeeds

❯ echo "import { renderToString } from 'react-dom/server.js'; console.log(renderToString('example'))" | node --input-type=module
example

but ESM without extension fails

❯ echo "import { renderToString } from 'react-dom/server'; console.log(renderToString('example'))" | node --input-type=module
node:internal/process/esm_loader:94
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/pete/Code/purescript/purescript-react-basic-dom/node_modules/react-dom/server' imported from /Users/pete/Code/purescript/purescript-react-basic-dom/[eval1]
Did you mean to import react-dom/server.js?
    at new NodeError (node:internal/errors:372:5)
    at finalizeResolution (node:internal/modules/esm/resolve:437:11)
    at moduleResolve (node:internal/modules/esm/resolve:1009:10)
    at defaultResolve (node:internal/modules/esm/resolve:1218:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:580:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:294:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
    at link (node:internal/modules/esm/module_job:78:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'ERR_MODULE_NOT_FOUND'
}

If I add an exports field to node_modules/react-dom/package.json like

  "exports": {
    ".": "./index.js",
    "./server": "./server.js"
  }

then ESM without extension works

❯ echo "import { renderToString } from 'react-dom/server'; console.log(renderToString('example'))" | node --input-type=module
example

@kaol
Copy link
Author

kaol commented Jun 16, 2022

Huh that's very weird. I can work on a hotfix release tomorrow. I'm only on my phone but any idea why this isn't being picked up by the GitHub actions?

" 1 workflow awaiting approval
First-time contributors need a maintainer to approve running workflows."

@mjrussell
Copy link
Member

Sorry I meant why the existing checks didn't catch this error, since Pete was able to reproduce it so easily. I can take a look at them in the morning. Thanks for this PR

@kaol
Copy link
Author

kaol commented Jun 16, 2022

I can't say that I understand the ES6 module system all that well. After some combination of yarn upgrades and yarn installs, the current version in master started working with our project and my version broke with

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './server.js' is not defined by "exports" in /home/kaol/src/affresco/apps/mosaico/node_modules/react-dom/package.json imported from /home/kaol/src/affresco/apps/mosaico/output/React.Basic.DOM.Server/foreign.js

I'd just close my PR but since you reproduced my original issue, I don't know what's up with this then. I'd advise against using my PR at least.

@kaol kaol marked this pull request as draft June 16, 2022 09:30
@pete-murphy
Copy link
Member

pete-murphy commented Jun 16, 2022

why the existing checks didn't catch this error

It seems like spago build doesn't catch bad import paths on the FFI side. Like export * as broken from "module-doesnt-exist" would be a runtime error if broken is called from PS. So a test file would have caught it I think. Not sure what to make of the error disappearing after yarn updates 🤔

@pete-murphy
Copy link
Member

Seems there was an exports field added recently: facebook/react#23252

@mjrussell
Copy link
Member

mjrussell commented Jun 16, 2022

It looks like the problem is probably due the fact that the current package.json expects ^17.0.0 of react-dom and that export was added in ^18.0.0. This is a bit tricky, I think the correct thing would be to fix this using the change in the PR, but it sounds like that will break for 18, then do a new version for React 18 (most of the react-basic does not yet support React 18)

@mjrussell
Copy link
Member

This would be my recommendation - #39. Merge that and release as 5.0.1, then we can do a 6.0.0 for React 18

@mjrussell
Copy link
Member

mjrussell commented Jun 18, 2022

5.0.1 released - https://github.com/lumihq/purescript-react-basic-dom/releases/tag/v5.0.1.

Thanks for reporting this!

@mjrussell mjrussell closed this Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants