prashantpalikhe / nuxt-ssr-lit

SSR support for Lit elements in Nuxt3
Other
42 stars 7 forks source link

@material/web md-filled-button throws in preview #102

Closed vosamoilenko closed 8 months ago

vosamoilenko commented 9 months ago

Describe the bug

When building and previewing a project, using the md-filled-button component from @material-web@1.0.0 triggers a customElements.get(...) is not a constructor error. This error originates from @lit-labs/ssr/lib/lit-element-renderer.js:18:24. It works in dev mode but not in preview.

To Reproduce

  1. npm install @material/web@1.0.0
  2. npm install nuxt-ssr-lit@1.6.3
  3. Add to nuxt config ["nuxt-ssr-lit", { litElementPrefix: ["md-"] }],
  4. Use component
    
    <script setup>
    import "@material/web/button/filled-button";
    </script>
5. Build and preview a project with
`npm run build && npm run preview`

**Expected behavior**
Page is rendered with a button 

 - Nuxt version: ^3.7.4
 - Browser: not relevant but Chrome
 - Version: not relevant but 117.0.5938.149

**Additional context**
console error logs

Starting preview command: node ./server/index.mjs 12:37:57 AM 12:37:57 AM Listening on http://[::]:3000 [nitro] [unhandledRejection] TypeError: customElements.get(...) is not a constructor at new LitElementRenderer (file:///users/project/frontend/.output/server/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:18:24) at createLitElementRenderer (file:///users/project/frontend/.output/server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:43:20) at ssrRender (file:///users/project/frontend/.output/server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:107:22) at renderComponentSubTree (/users/project/frontend/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9) at renderComponentVNode (/users/project/frontend/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12) at renderVNode (/users/project/frontend/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14) at renderComponentSubTree (/users/project/frontend/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7) at /users/project/frontend/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:369:25 [nuxt] [request error] [unhandled] [500] customElements.get(...) is not a constructor at new LitElementRenderer (./server/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:18:24)
at createLitElementRenderer (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:43:20)
at ssrRender (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:107:22)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)
at ./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:369:25 (node:16086) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1) (Use node --trace-warnings ... to show where the warning was created) [nuxt] [request error] [unhandled] [500] customElements.get(...) is not a constructor at new LitElementRenderer (./server/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:18:24)
at createLitElementRenderer (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:43:20)
at ssrRender (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:107:22)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7) [nuxt] [request error] [unhandled] [500] customElements.get(...) is not a constructor at new LitElementRenderer (./server/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:18:24)
at createLitElementRenderer (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:43:20)
at ssrRender (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:107:22)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7) [nuxt] [request error] [unhandled] [500] customElements.get(...) is not a constructor at new LitElementRenderer (./server/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:18:24)
at createLitElementRenderer (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:43:20)
at ssrRender (./server/chunks/app/_nuxt/LitWrapperServer-4ce61cd2.mjs:107:22)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:423:9)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)
at renderComponentVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
at renderVNode (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
at renderComponentSubTree (./server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)

prashantpalikhe commented 8 months ago

Thanks for reporting the issue @vosamoilenko

I will have a look

prashantpalikhe commented 8 months ago

Looks like the component import gets cleaned up during the nuxt build.

Something that will work for you is to add the import to your Nitro moduleSideEffects.

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [["nuxt-ssr-lit", { litElementPrefix: ["md-"] }]],
  nitro: {
    moduleSideEffects: ['@material/web/button/filled-button'],
  },
})

Of course, this is not ideal. But I don't think this is an issue to be fixed on this module's end. Maybe try filing an issue on Nitro?

prashantpalikhe commented 8 months ago

Looking into Nitro's source, we can actually just pass @material/web to the moduleSideEffects. So that you do not have to maintain a list of all the components you use in the project.

So something like this works:

export default defineNuxtConfig({
  modules: [["nuxt-ssr-lit", { litElementPrefix: ["md-"] }]],
  nitro: {
    moduleSideEffects: ['@material/web']
  },
})
prashantpalikhe commented 8 months ago

Also, good to know is for the SSR to work entirely, the component library should also be SSR compatible. Lit shims only a handful of DOM APIs on the server. If the component library uses APIs on lifecycle hooks that run on the server but are not available on the server, then that will be an issue.

prashantpalikhe commented 8 months ago

Closing this, since this is fixable on your end.

vosamoilenko commented 8 months ago

thanks for investigation and advices!