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

Suggest an official way to use libraries *only* on the client #796

Closed
Hubro opened this issue Mar 13, 2023 · 12 comments
Closed

Suggest an official way to use libraries *only* on the client #796

Hubro opened this issue Mar 13, 2023 · 12 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@Hubro
Copy link

Hubro commented Mar 13, 2023

Some libraries are designed and compiled to run in the browser and can't work with SSR.

Most of the time (I think) it's sufficient to simply disable that library on the server and just render a spinner instead. Sure, you won't get the benefits of SSR for that specific library, but the rest of your application still gets to reap the benefits of smooth routing, data loading and sweet, sweet streaming rendering.

I'm struggling with this issue with ag-grid. I want to use solid-start for the seamless data loading and streaming rendering. However, on one specific subpage, I want to use ag-grid to display some data. It's more than adequate for me to have this page display a loading spinner until the data and the ag-grid library is loaded.

However, I can't figure out how to completely divorce the ag-grid library from the server side. When I build my project, the server side bundle crashes during build because of ag-grid, even though I lazy load the library.

I'm guessing this is a common enough use case that there should be an official, recommended procedure for including client-only libraries that are not included in the server bundle.

This would be great as a subpage of the docs, perhaps titled "Client-only libraries" or "Disable SSR for specific libraries".

@peerreynders
Copy link

peerreynders commented Mar 13, 2023

So isServer isn't cutting it?

Example: useServerContext

@arbassett
Copy link
Contributor

There is a unstable_clientOnly import util that works exactly like lazy but it will only render it on the client.. i've done some work in #744 to make this possible and a tracking issue #739.

here is a example that i used to get the monaco editor working https://stackblitz.com/edit/solid-ssr-vite-bkw6w8?file=package.json,src%2Froutes%2Findex.tsx%3AL10

@Hubro
Copy link
Author

Hubro commented Mar 13, 2023

So isServer isn't cutting it?

Example: useServerContext

I tried it now:

const AgGridSolid = lazy(() => {
  if (isServer) {
    throw "THIS SHOULD NEVER RUN ON THE SERVER";
  } else {
    return import("ag-grid-solid");
  }
});

The server bundle build still fails with the same error:

Error [RollupError]: "template" is not exported by "../../../node-modules-hub/test-project/node_modules/.pnpm/solid-js@1.6.11/node_modules/solid-js/web/dist/server.js", imported by "../../../node-modules-hub/test-project/node_modules/.pnpm/ag-grid-solid@29.1.0_jfjxpl5li6ugpqr2h3tzst4lni/node_modules/ag-grid-solid/dist/esm/index.js".
    at error (file:///home/tomas/node-modules-hub/dollarscope/node_modules/.pnpm/rollup@3.18.0/node_modules/rollup/dist/es/shared/node-entry.js:2105:30)
    at Module.error (file:///home/tomas/node-modules-hub/dollarscope/node_modules/.pnpm/rollup@3.18.0/node_modules/rollup/dist/es/shared/node-entry.js:13174:16)
    at Module.traceVariable (file:///home/tomas/node-modules-hub/dollarscope/node_modules/.pnpm/rollup@3.18.0/node_modules/rollup/dist/es/shared/node-entry.js:13559:29)
    ...

Am I using it in a way that is incompatible with tree-shaking? 🤔 Or does it just not work?

@Hubro
Copy link
Author

Hubro commented Mar 13, 2023

There is a unstable_clientOnly import util that works exactly like lazy but it will only render it on the client

Tried that now:

const AgGridSolid = unstable_clientOnly(() => {
  return import("ag-grid-solid");
});

Server build still fails with the exact same error, unfortunately 🤔 But as you linked a tracking issue, I assume it's not supposed to work yet.


➜ pnpm list | cat

dependencies:
@prisma/client 4.11.0
@solidjs/meta 0.28.2
@solidjs/router 0.7.0
ag-grid-community 29.1.0
ag-grid-solid 29.1.0
papaparse 5.4.0
prisma 4.11.0
solid-js 1.6.11
solid-start 0.2.23
undici 5.20.0

devDependencies:
@trivago/prettier-plugin-sort-imports 4.1.1
@types/node 18.14.2
@types/papaparse 5.3.7
autoprefixer 10.4.13
date-fns 2.29.3
postcss 8.4.21
prettier 2.8.4
prettier-plugin-tailwindcss 0.2.4
solid-start-node 0.2.23
tailwindcss 3.2.7
ts-node 10.9.1
typescript 4.9.5
typescript-language-server 3.3.0
vite 4.1.4

@peerreynders
Copy link

Am I using it in a way that is incompatible with tree-shaking? thinking Or does it just not work?

The dynamic import may be messing with the tree-shaking.

Rollup has open issues regarding this problem.

The workaround is to create a façade module.

@arbassett
Copy link
Contributor

arbassett commented Mar 14, 2023

@Hubro i forgot to add im my previous comment you also need to add ag-grid-solid to your ssr external

  ssr: {
    external: ['ag-grid-solid'],
  },

if that doesn't work instead of importing ag-grid-solid with clientOnly create your own component and treat your component as the boundary for clientOnly like in my example i made a Editor.tsx file that just imported monaco as normal but in the router i imported it with clientOnly

if that still doesn't work please create a example on stackblitz or other sites.

Server build still fails with the exact same error, unfortunately 🤔 But as you linked a tracking issue, I assume it's not supposed to work yet.

It is working as im using it myself atm for monaco the tracking is to ensure that it works on all adapters.

@Hubro
Copy link
Author

Hubro commented Mar 14, 2023

i forgot to add im my previous comment you also need to add ag-grid-solid to your ssr external

That works! That's awesome 🙂

If I don't use a facade module, the entirety of ag-grid is added to my index.js after build. If I use a facade module, then the facade module gets the entire bulk of ag-grid instead, which is preferable, but I get this warning during build:

"default" is imported from external module "ag-grid-solid" but never used in ".solid/server/assets/AgGridSolid-2ddd4236.js".

I know I can just ignore this, but I don't like getting in the habit of ignoring warnings. Is there any way to get rid of this warning?


AgGridSolid.tsx:

import AgGridSolid from "ag-grid-solid";

export default AgGridSolid;

@arbassett
Copy link
Contributor

I know I can just ignore this, but I don't like getting in the habit of ignoring warnings. Is there any way to get rid of this warning?

the best way to do this would be to turn that facade module into a component and use it there.

@peerreynders
Copy link

the best way to do this would be to turn that facade module into a component and use it there.

@Hubro You're going to want to do this anyway.

unstable_clientOnly() essentially means "Client-Only Component" i.e. it does the heavy lifting of replacing the server fallback content that was SSRed with the client-side component in the browser.

So it's a way to use client-only components rather than a way to control client side imports (which would leave you with additional work).

@lxsmnsyc
Copy link
Member

So isServer isn't cutting it?

Example: useServerContext

isServer is highly discouraged because it may cause hydration mismatches.

There's two ways right now to solve this but the safest way would be to use unstable_clientOnly

@ryansolid
Copy link
Member

Yeah this is an area still under design because of things like this. Ideal the dependency graph could be isolated this way.

@ryansolid ryansolid added documentation Improvements or additions to documentation enhancement New feature or request labels Apr 4, 2023
@ryansolid
Copy link
Member

This is fixed in the new Solid Beta.

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 #1139 for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants