question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SSR CSS injection in development

See original GitHub issue

Relevant previous issues / discussion:

User-land vue-specific patch that (partially, see NOTE below) works for me (haven’t seen how it hydrates yet) –

/* relevant snippet from server.js */
const cssUrls = new Set(), cssJsUrls = new Set()
function collectCssUrls(mod) {
  mod.importedModules.forEach(submod => {
    if (submod.id.match(/\?vue.*&lang\.css/)) return cssJsUrls.add(submod.url)
    if (submod.file.endsWith(".css")) return cssUrls.add(submod.url)
    if (submod.file.endsWith(".vue")) return collectCssUrls(submod)
    /* TODO include js files like routes that include other components */
    if (submod.file.match(/route/)) return collectCssUrls(submod)
  })
}
let render
if (!isProd) {
  render = (await vite.ssrLoadModule("/src/entry-server.js")).render
  const mod = await vite.moduleGraph.getModuleByUrl('/src/app.js') /* TODO replace with your entry */
  cssUrls = mod.ssrTransformResult.deps.filter(d => d.endsWith(".css"))
} else {
  render = require("./dist/server/entry-server.js").render
}
const [appHtml] = await render(url, manifest)
const devCss = [...cssUrls].map(url => {
  return `<link rel="stylesheet" type="text/css" href="${url}">`
}).join("") + [...cssJsUrls].map(url => {
  return `<script type="module" src="${url}"></script>`
}).join("")
const html = template.replace(`<!--app-html-->`, appHtml).replace(`<!--dev-css-->`, devCss)

Curious about latest thoughts on this!

NOTE: It looks like there is some non-determinism to the above… sometimes css modules are missing…

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:12 (10 by maintainers)

github_iconTop GitHub Comments

3reactions
egoistcommented, Feb 27, 2021

I just inlined the css as <style> tags in the HTML:

const collectCssUrls = (mods: Set<ModuleNode>, styles: Map<string, string>) => {
  for (const mod of mods) {
    if (mod.ssrModule && mod.file && mod.id) {
      if (mod.file.endsWith('.css') || /\?vue&type=style/.test(mod.id)) {
        styles.set(mod.url, mod.ssrModule.default)
      }
    }
    if (mod.importedModules.size > 0) {
      collectCssUrls(mod.importedModules, styles)
    }
  }
}

Some changes need to be made in updateStyle in order to make hydration work, or at least expose sheetsMap and leave that to users:

https://github.com/vitejs/vite/blob/89e0e33b66ecf199fedce18628f0c382e45f93a6/packages/vite/src/client/client.ts#L195

2reactions
ferdinando-ferreiracommented, May 25, 2021

Do you have any ideas / suggestions on how to proceed?

I posted a working implementation on the other issue. Both the attempts from this issue and the alternative I proposed use artifacts of the internal build process, which leads to instability.

Here is a way to test

git clone https://github.com/ferdinando-ferreira/vite.git --single-branch -b before-merge before-merge
cd before-merge
yarn
yarn build
cd packages/playground/ssr-vue
yarn dev

After that open localhost:3000, the html will have the styles embedded.

It is a small change from ssr-vue from the playground of this very repository, the minimal test case to show how to do it, here are the changes from the vanilla ssr-vue: https://github.com/ferdinando-ferreira/vite/commit/e70bd50575bdf8413d77fbd0d10c0e669f1b3dcb

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced (LEGACY) - MUI System
By default, the style tags are injected last in the <head> element of the page. They gain more specificity than any other style...
Read more >
Server-Side Rendering (SSR) - Vue.js
Overview #. What is SSR? #. Vue.js is a framework for building client-side applications. By default, Vue components produce and manipulate DOM in...
Read more >
How I made it easy to develop on Vue.js with server-side ...
In my new project I decided to use Vue.js. I needed server-side rendering (SSR), CSS modules, code-splitting and more cool things.
Read more >
Why insert style again on client-side when using ssr? (from ...
why should we inject CSS again on client-side if it's already injected server-side? Is there any difference between client-side cache and server ...
Read more >
esbuild CSS Modules Plugin for Server-Side Rendering
I found this quite challenging when developing my Serverless React SSR template. I am using the esbuild JS bundling tool quite extensively ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found