Closed thetarnav closed 9 months ago
That is strange to say the least. I wouldn't expect a development condition showing up in prod. I believe the only place we touch this is in the vite-plugin-solid. https://github.com/solidjs/vite-plugin-solid/blob/master/src/index.ts#L327.. and in the adapters which definitely don't include "development"
If I switch the order of conditions (prod above dev), the prod entry is taken both in dev and prod in SolidStart. I believe I was using the default node adapter.
I've noticed rollup node resolve plugin is kinda broken in the last 2 major versions.. can you check what version you are on. 13 seems fine. 14/15 not so much.
You're right. Overriding @rollup/plugin-node-resolve
dependency to 13.3.0
fixed it. Solid exports are used accordingly in development/server/production.
Yeah something is really broken here just don't know what.
Seems like ark-ui is giving up on solid-start for now due to something related to this issue.
https://github.com/chakra-ui/ark/issues/1363
In setting up for SolidStarts next Beta Phase built on Nitro and Vinxi we are closing all PRs/Issues that will not be merged due to the system changing. If you feel your issue was closed by mistake. Feel free to re-open it after updating/testing against 0.4.x release. Thank you for your patience. See https://github.com/solidjs/solid-start/pull/1139 for more details.
I'm going to transfer this one to docs instead. General how to make a package for SSR is good thing to have.
The Node.js exports
thing something to avoid (imo) because it is not part of the ES Module standard. I avoid it altogether, and find other means to do dev vs prod (f.e. set env vars, give devs the tools to configure whether their build will compile out the branches or not, but by default leave the branches in and don't shipped multiple formats of the code stripped and non-stripped).
They are not out in Node.js yet, but standard importmap
s are a lot better because:
exports
, but not import maps)With import maps, users will be able to opt into dev vs prod in a more explicit way. This will be great because the current automatically-try-to-guess method embedded in the tooling can leave people stuck and feeling out of control when issues like that one from Chakra happen, especially in the many possible use cases for Solid.js outside of components (f.e. server apps, data manipulation, state management libraries, etc, where SSR, loading mock APIs, dev vs prod, etc, may not be concerns and these roadblocks get in the way of doing great things).
Here's a sample of importmap flexibility, where we can override a specific file from a package with another:
https://codepen.io/trusktr/pen/KKEPGYB?editors=1010
Keep an eye out for Node import maps, because this is something we should align with!
In the meantime, besides the above, this this 160-line-long exports
field monster is a problem (in my opinion):
If I could make the choice, it would be deleted, and Solid would ship vanilla standard ES modules, and then Solid would build the tooling around that instead of around Node.js, making Solid easily portable and more interoperable.
Building around Node.js is locking into non-standard ways of doing things that will not progress forward very well, especially for a library that is a client-side library, unlike Node.js packages that are intended for Node.js runtime only. The exports
field is designed specifically for Node.js runtime libraries, and relying on this for a mostly-browser library is just not ideal.
The future is libraries/frameworks that simply work based on standards that are buildless-first, without any issues like the Chakra issue, but that have opt-in tooling to achieve what is needed (f.e. prod vs dev, srr vs client, etc).
I highly recommend (highly wish) for Solid.js to become as vanilla as possible, which not only simplifies things for users that want to use Solid.js in any way besides the default way with Solid's default tooling, but will also simplify maintenance.
There is a better way. People have been doing dev vs prod builds (etc) long before Node.js exports
existed.
src/
into dist/
with declarations. Do not ship bundles.exports
main
field to dist/index.js
which is compiled from src/index.js
(or dist/solid.js
if the entry is src/solid.js
, etc)
main
pointing to the dev
file (still no exports
field). Let tooling or import maps handle replacing the dev file with the prod file, while the package is still as close to plain ESM (just more files).types
field to dist/index.d.ts
(or dist/solid.d.ts
if the entry was src/solid.js
, etc)As far as the library structure, that's it! You are done! Super simple.
Benefits:
solid-js
is installed, and it just workshtml
template tags or not (like Lit's new compiler), with a 100% opt-in experience beyond the super basic package setup.If someone from core officially endorses trying out a simpler setup, I will be willing to help prototype it.
Here's one of my packages (which as you might guess, follows those ideas):
https://github.com/lume/element
I've committed the dist/
folder so it is all easy to see from the repo (commiting dist/
is not on my list of recommendations, but for my needs this makes it easy to clone the lume
super repo and everything works out of the box with no build, which is something I valued, and makes live vanilla demos like this one possible: https://raw.githack.com/lume/lume/develop/examples/gltf-model.html).
We can see that https://github.com/lume/element/blob/main/src/index.ts maps to https://github.com/lume/element/blob/main/dist/index.js along with sibling source map and declaration files. The same applies to other files.
main
and types
fields simply point to dist/index.js
and dist/index.d.ts
.
solid-js
, Go-To-Definition on a Solid API goes to a declaration file, but often we want to look at implementation.
@lume/element
API and you'll be taken to its source, with comments and everything. Useful for learning.solid-js
is it not at all clear that a bunch of its code comes from a package called dom-expressions
. That's because the dom-expressions package is copied into solid-js when building solid-js locally.
@lume/element
, it is crystal clear where all code come from.signals.ts
), they cannot.
@lume/element
, just import from a specific file to get a piece of its API, and you will also get type definitions for the file by default because TypeScript by default looks for sibling declaration files.@lume/element
we can easily replace its files. Ideally we split things out into small enough files that functionalities are self-contained, easy to replace.I can think of more.
An ES module setup as close to vanilla as possible is simply the way to go. Maximal ease, portability, longevity, and interoperability.
Let's please 🙏 consider this for Solid 2.0. I see we're already going in the same direction:
My 2 cents: Yesterday I went to inspect getRequestEvent
, which took me to a declaration file, which had no reference to dom-expressions
at all, so I had to go to github and use global search for it in solid start, solid and finally dom-expressions...
Not sure if other IDEs can do it, but at least the current behaviour with the TS language server for vim isn't great (I assume it's similar with other tools). If it's possible to go to the source directly, that would be great, also being able to consume just signals would be cool as well!
Yep, it would be nice!
Not sure if other IDEs can do it
IDEs will never be able to do it because generic IDEs are not designed to specifically understand Solid's bespoke file copying pipeline. Only a hypothetical IDE plugin made by Solid team could enable it (wouldn't be worth it).
do not use exports
@trusktr I agree with your suggestion to support import maps if someone is interested in using them, but I don't think it is a good idea to break the Nodejs exports. Nodejs has its own standard that many tools support. Breaking the tooling in each new version is a huge mistake that can hinder the adoption of newer versions.
If Solid 2.0 will already be an ecosystem breaking change, and if all of Solid's prescribed tools that the team manages (f.e. app generators, Solid Start, any plugins for vite/babel/etc) are updated to work on 2.0, then this change will be for the better.
A clear migration path should be defined. I will gladly help write this.
Here's just one more example of problem with the current setup:
Which do I auto-complete? Devs should just see one option: "I just want X thing from solid.js".
This will be a philosphical question for core team: "how much does Solid.js want to be able to move forward, and how much does it want to stay full backwards compatible"?
React takes it to the extreme on one end of the spectrum at almost 100% backwards compatibility with one main notable change being the one to setState
in class components when it went from sync to async, but that was basically all.
On the other hand, Three.js has the most simple package setup that will last forever, making maintenance as simple as possible, and it makes breaking ecosystem-changes when it determines it is for the better future (it has a 10 month deprecation cycle and anything can break in 10 months for the better), and provides a very nice migration guide along the way. And look at Three, it is doing great. The ecosystem is huge for being in a niche area as opposed to normal non-WebGL/GPU web development.
Solid.js started as a passion free time unpaid non-corporate project aiming to be one of the best and most innovative. Will Solid continue to strive for that? If so, breaking changes wiill be a must.
I am all on for improvements and innovation, but I do not consider import maps superior to Nodejs exports. It's just a matter of different standards. Browsers sometimes have fallen behind the innovations of Nodejs, and I do not necessarily think import maps are inherently better. I respect your choice if you're on the team with "browsers and no local tooling", but it should be considered that many people are not, and there are many benefits from other perspectives.
So, a yay for innovation, but a nay for breaking things for the sake of a change.
Consolidated this into #473
How should library authors set up export conditions to have separate entries for dev and prod? I'm making a tsup preset that would automatically configure those when building a library, this is just the last part that isn't working quite right.
This configuration works in the vite templates.
dev.jsx
is loaded in development andindex.jsx
in production when building. But In solid-start thedev.jsx
entry is taken in both cases.Having a separate entry for the server works without issues though.