pmndrs / lamina

🍰 An extensible, layer based shader material for ThreeJS
MIT License
1.01k stars 41 forks source link

Using with Sveltekit #35

Open nilskj opened 2 years ago

nilskj commented 2 years ago

Fantastic lib! I'm using it in my svelte-kit app (with pnpm). First I get these worrying error messages, is there a way to only import the vanilla parts of this?

image

It does however run and work very nice in dev, but when building for production I face this error:

image

I see the package both provides a .cjs and a .js esm export, and I do try importing the esm one like this:

image

Any idea on how I should configure vite to be able to build this?

nilskj commented 2 years ago

When trying to follow what is purposed in the error message and import it like this instead:

image

Vite throws another error:

image
FarazzShaikh commented 2 years ago

Thanks!

I’m not too familiar with Svelte but I am guessing this is pnpm problem. Can you try installing it with Npm or Yarn to see if it works?

The way it works is that it still needs React in there but React won’t end up in your bundle if you only use Lamina/vanilla

CodyJasonBennett commented 2 years ago

R3F should be optional here alongside react.

https://github.com/FarazzShaikh/THREE-CustomShaderMaterial/blob/2696b65c381e0113ea3ad4f8091004d7280d1b0f/package.json#L75-L84

FarazzShaikh commented 2 years ago

Right, I will fix that thanks!

AlexWarnes commented 2 years ago

Ran into the same issue using lamina with SvelteKit! My workaround was to turn off ssr (I did it for my whole project, but pretty sure you could just disable it for the routes that use lamina):

Create a hooks.ts (or .js) in your src directory, and then disable ssr with:

import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
    return await resolve(event, { ssr: false });
};

I don't understand exactly how this all works, but it got me through the build. For reference: https://github.com/AlexWarnes/lamina-spatula/blob/main/src/hooks.ts

CodyJasonBennett commented 2 years ago

Yikes, prob best to let Sveltekit know of that issue with package resolution with SSR -- that can load multiple versions of libraries and cause deeper breakage.

Another issue with their bundler's interop of non-default exports, but import * as pkg from 'lamina/vanilla' should workaround for now.

FarazzShaikh commented 2 years ago

@nilskj I have updated the deps like Cody mentioned. Let me know if the error is gone or is different

nilskj commented 2 years ago

Thank you all for quick help. I see @AlexWarnes (awesome project btw), disabling SSR makes it build, but I don't want to disable SSR since my project is a website and this particular page with the 3D stuff needs some server rendering.

When upgrading lamina I see the package deps have updated:

image

but when doing a pnpm install I get this (even worse then before, with router-dom?)

- lamina 1.1.18
+ lamina 1.1.19

 WARN  Issues with peer dependencies found
.
└─┬ lamina
  β”œβ”€β”€ βœ• missing peer react@>=18.0
  β”œβ”€β”€ βœ• missing peer react-dom@>=18.0
  β”œβ”€β”€ βœ• missing peer @react-three/fiber@>=8.0
  β”œβ”€β”¬ leva
  β”‚ β”œβ”€β”€ βœ• missing peer react@>=16.8.0
  β”‚ β”œβ”€β”€ βœ• missing peer react-dom@>=16.8.0
  β”‚ β”œβ”€β”¬ @radix-ui/react-portal
  β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react-dom@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-primitive
  β”‚ β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ └─┬ @radix-ui/react-slot
  β”‚ β”‚ β”‚   β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚   └─┬ @radix-ui/react-compose-refs
  β”‚ β”‚ β”‚     └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ └─┬ @radix-ui/react-use-layout-effect
  β”‚ β”‚   └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”œβ”€β”¬ @radix-ui/react-tooltip
  β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react-dom@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-context
  β”‚ β”‚ β”‚ └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-id
  β”‚ β”‚ β”‚ └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-popper
  β”‚ β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-arrow
  β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ β”‚ └─┬ @radix-ui/react-primitive
  β”‚ β”‚ β”‚ β”‚   └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-use-rect
  β”‚ β”‚ β”‚ β”‚ └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ └─┬ @radix-ui/react-use-size
  β”‚ β”‚ β”‚   └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-portal
  β”‚ β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ └── βœ• missing peer react-dom@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-presence
  β”‚ β”‚ β”‚ └── βœ• missing peer react@>=16.8
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-use-controllable-state
  β”‚ β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”‚ └─┬ @radix-ui/react-use-callback-ref
  β”‚ β”‚ β”‚   └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-use-escape-keydown
  β”‚ β”‚ β”‚ └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ β”œβ”€β”¬ @radix-ui/react-use-previous
  β”‚ β”‚ β”‚ └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”‚ └─┬ @radix-ui/react-visually-hidden
  β”‚ β”‚   └── βœ• missing peer react@"^16.8 || ^17.0"
  β”‚ β”œβ”€β”¬ @stitches/react
  β”‚ β”‚ └── βœ• missing peer react@">= 16.3.0"
  β”‚ β”œβ”€β”¬ @use-gesture/react
  β”‚ β”‚ └── βœ• missing peer react@">= 16.8.0"
  β”‚ β”œβ”€β”¬ @welldone-software/why-did-you-render
  β”‚ β”‚ └── βœ• missing peer react@"^16 || ^17"
  β”‚ β”œβ”€β”¬ react-colorful
  β”‚ β”‚ β”œβ”€β”€ βœ• missing peer react@>=16.8.0
  β”‚ β”‚ └── βœ• missing peer react-dom@>=16.8.0
  β”‚ β”œβ”€β”¬ react-dropzone
  β”‚ β”‚ └── βœ• missing peer react@">= 16.8"
  β”‚ └─┬ zustand
  β”‚   └── βœ• missing peer react@>=16.8
  └─┬ three-custom-shader-material
    β”œβ”€β”€ βœ• missing peer react@>=18.0
    └── βœ• missing peer @react-three/fiber@>=8.0
βœ• Conflicting peer dependencies:
  react      react-dom  
Peer dependencies that should be installed:
  @react-three/fiber@>=8.0.0  

I made a new svelte-kit app and used normal npm instead of pnpm and then I don't get these errors so I don't know if they are about pnpm.

If I tried changing to your workaround @CodyJasonBennett, like this:

image

I get another error, this time with the three import:

/Users/nilskjellman/Dev/svelte-kit-app/node_modules/.pnpm/lamina@1.1.19_three@0.139.2/node_modules/lamina/vanilla.js:1
import * as THREE from 'three';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1032:15)
    at Module._compile (node:internal/modules/cjs/loader:1067:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:168:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:197:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
[SyntaxError: Cannot use import statement outside a module]

All here above reproduced in an empty sveltekit app. npm init svelte app-name

CodyJasonBennett commented 2 years ago

I think these are clearly pnpm and svelte issues, if you could forward these to their respective repositories.

benmccann commented 2 years ago

That error message is coming from Node.js. It looks to me like the problem is that this library is using file extensions that are not valid with Node. The ESM version needs to end with .mjs unless you have "type": "module". If I rename vanilla.js to vanilla.mjs then I make it further. It looks like that change would need to be made throughout the project.

CodyJasonBennett commented 2 years ago

That is also an issue with three (they go halfway with three.cjs and three.module.js), but I don't think it's reasonable to expect everyone to follow Node's conventions for ESM in web-only libraries. In any case, there are still issues evident with interop since CJS on the server-side should merely be an implementation detail to users that are otherwise writing with ES6 syntax.

benmccann commented 2 years ago

You only ever need to go halfway. If you have "type": "module" you need the .cjs ending and if you don't then you need the .mjs ending.

This really isn't anything Svelte or pnpm can change as neither are responsible for this. The page is being rendered during SSR and so the libraries get loaded. The user could load the libraries only on the client, but it's harder / uglier to set that up and it'd be much nicer if it just used file endings that work. It's all hidden to the user, so there's no real downside to changing the extensions

CodyJasonBennett commented 2 years ago

I see, you mean in regards to Node resolution -- three has resolved this already (via type="module" and .cjs), and we still need to do the same here in Lamina.

If I'm understanding you correctly, we'd need type="module" in addition to the rest of this config?

https://github.com/pmndrs/lamina/blob/7c6ad545b2c05ee4750d1456190473451be9b25b/package.json#L2-L8

benmccann commented 2 years ago

You don't necessarily have to add "type": "module" - you could rename the ESM file to have an .mjs ending. But the version you posted looks like it would work as well

AlexWarnes commented 1 year ago

Wanted to expand on the previous solution for future reference as some things have changed with SvelteKit and, like you mentioned @nilskj, disabling SSR is not at all ideal! (and I've had this issue with other dependencies as well)

Option 1 In your vite.config.js include lamina and three-custom-shader-material in the ssr.noExternal array like:

const config = {
    ssr: {
        noExternal: [
            'three', 
            'lamina',
            'three-custom-shader-material',
        ]
    },
    plugins: [sveltekit()],
};

Option 2 You can of course still disable SSR if you want (with or without the vite config changes). And now you can do it at the page level by export const ssr = false in your route level +page.server.js

Disclaimer And to reiterate, this is not my area of expertise, but option 1 above feels like a better solution so I thought I'd share. For reference I'm using it here for lamina and postprocessing: https://github.com/AlexWarnes/photon/blob/main/vite.config.js

shot-codes commented 1 year ago

Hm, I'm having issues using lamina in a sveltekit project. I see the missing dependencies message, and my imports from lamina/vanilla all resolve to undefined at runtime (in my editor typescript is happy). If I make the suggested changed to vite.config.ts I get a different error when trying to import lamina: require is not defined