solid icon indicating copy to clipboard operation
solid copied to clipboard

Importing solid-js/web (as ESM, from Node.js) throws a SyntaxError

Open vinsonchuong opened this issue 2 years ago • 4 comments

Describe the bug

When I import solid-js/html as an ES module from Node.js, I get the following error:

SyntaxError: The requested module 'solid-js/web' does not provide an export named 'Aliases'

Your Example Website or App

n/a

Steps to Reproduce the Bug or Issue

For example, in the Node.js REPL:

>> node
Welcome to Node.js v21.1.0.
Type ".help" for more information.
> await import('solid-js/html')
file:///home/vinsonchuong/projects/test-tube/node_modules/solid-js/html/dist/html.js:15
  Aliases,
  ^^^^^^^
Uncaught:
SyntaxError: The requested module 'solid-js/web' does not provide an export named 'Aliases'

Expected behavior

I expect the import to succeed and not throw an error.

Screenshots or Videos

No response

Platform

  • OS: Linux
  • Browser: Running in Node.js v21.1.0
  • Version: 1.8.7

Additional context

I'm looking to write some custom tooling for writing automated tests from Node.js and was surprised to see this error.

After some searching, I found this issue: https://github.com/solidjs/solid/issues/1483, which clued me into the fact that there are separate builds for the browser and for Node.js.

It looks like because the html tag function returns a DOM Node, solid-js/html is a browser-only package. I am, however, able to proceed if I configure Node.js to prefer browser packages:

>> node --conditions browser
Welcome to Node.js v21.4.0.
Type ".help" for more information.
> await import('solid-js/html')
[Module: null prototype] { default: [Function: html] }

Because solid-js/html imports solid-js/web, there's no way to specify that the browser packages should be used without passing in arguments to Node.js. To make this easier, could solid-js/html directly import the browser build of solid-js/web instead? There are probably trade-offs to doing that, but I'm hoping to have easy ways to run Solid from a Node.js + JSDOM environment.

vinsonchuong avatar Dec 09 '23 21:12 vinsonchuong

So far we've pushed people to use "browser" export conditions for this. Like in solid-jest when doing testing we use the browser condition. We could make it use the browser version. Although there are 2 versions of Solid as well, and it is less clear what version you want. Like testing I want the browser reactive version, but for doing some sort of SSR you probably want the inert server version. To be fair right now because they all connect to the same condition it isn't that configurable.

Not sure. What I'm getting at it is this probably won't work correctly for everyone unless we treat it as browser across the board which can only be done through conditions as web internally doesn't wire to browser version of solid etc... It is interesting problem.

ryansolid avatar Dec 12 '23 20:12 ryansolid

Makes sense. It's pretty tough to hit every usecase gracefully.

When reading this section in solid-jest, I noticed that a user can choose the right preset to get what I assume to be the build of Solid that they want.

One of the reasons I'm using solid-js/html is, for simple projects, I tend towards not having a compiler.

So, I'm wondering if a similar concept can be applied here. Perhaps by importing something like solid-js/html/browser or solid-js/web/browser, we can get the hardcoded browser builds. I see that solid-js/web ends up importing solid-js. So, if solid-js/web/browser ended up importing solid-js/browser, that might be a graceful way to hit this usecase.

What do you think?

Edit: For additional context, I've found a decent workaround via a custom Node.js loader hook that rewrites imports for solid-js/* to the version that I want. I'm actually not able to use --conditions browser because that affects all packages, and I want the Node.js version of some packages.

A loader hook is a reasonable path, assuming that the test runner in use allows configuring Node.js arguments.

vinsonchuong avatar Dec 17 '23 22:12 vinsonchuong

I am hitting this issue in Vite/Vitest and am still looking for a workaround. Setting resolve.conditions is too intrusive in my use case and causes other side effects. So a direct kind of import would also be very helpful to me!

dan-lee avatar Dec 19 '23 20:12 dan-lee

I am hitting this issue in Vite/Vitest and am still looking for a workaround. Setting resolve.conditions is too intrusive in my use case and causes other side effects. So a direct kind of import would also be very helpful to me!

I think you are going have to depend aliasing then because this is a multi-package concern. While any package could just import from the right source (we expose dist) our core libraries which reference each other would not. Export conditions make sense here or bundler aliasing makes sense here but hard-coding the libraries doesn't particularly.

It doesn't really extend out well into the ecosystem either. We tend to ship as source to give maximum compilation flexibility to the end user so like intermediate libraries aren't going to do the combinatorics as well.

I think we should look at export conditions here a bit more and see if we can be more helpful in some way. Like we have a "server" export condition when people need that build regardless of node etc.. Maybe there is a way to get client that doesn't have other implications. That being said this hasn't been a problem for a lot of projects because the solid parts could be built with that setting and then the setting could be absent from the runtime when running.

ryansolid avatar Jan 03 '24 18:01 ryansolid