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

🐛 BUG: CSS from Vue single file component not consistently injected into HTML files #2575

Closed
lhermann opened this issue Feb 13, 2022 · 7 comments
Assignees
Labels
needs response Issue needs response from OP

Comments

@lhermann
Copy link

What version of astro are you using?

0.22.20

What package manager are you using?

npm

What operating system are you using?

Mac, Linux

Describe the Bug

Problem

Astro injects CSS from Vue single file components into HTML files like this:

<!DOCTYPE html>
  <html lang="en">
    <head>
      <!-- Global styles are always injected -->
      <link rel="stylesheet" href="./_static/main.4fe5491f.css">

      <!-- Vue styles (from vue single file components) are sometimes omitted -->
      <link rel="stylesheet" href="./_static/SiteLogo.vue_vue_type_style_index_0_scoped_true_lang.dbb54b6d.css">
      <link rel="stylesheet" href="./_static/Spinner.vue_vue_type_style_index_0_scoped_true_lang.d380df91.css">
      <link rel="stylesheet" href="./_static/SiteHeader.vue_vue_type_style_index_0_scoped_true_lang.40ec5b24.css">
      <link rel="stylesheet" href="./_static/HeroIllustration.vue_vue_type_style_index_0_lang.0934a099.css">
      <link rel="stylesheet" href="./_static/SiteFooter.vue_vue_type_style_index_0_scoped_true_lang.e3815133.css">
      <link rel="stylesheet" href="./_static/TestimonialSlider.vue_vue_type_style_index_0_scoped_true_lang.ed5a2afb.css">
      <link rel="stylesheet" href="./_static/ToggleButton.vue_vue_type_style_index_0_scoped_true_lang.0746df63.css">
      <link rel="stylesheet" href="./_static/index.ceac6cfd.css">
      [...]
    </head>
  [...]
</html>

The global CSS files (in this case just one main file) is consistently injected. But the CSS from .vue files is sometimes omitted. "Sometimes" you say? Yes, I have been running tests for about 4 hours now to find the cause and I could not find conditions to consistently reproduce the problem. At this point I am assuming a race condition.

Observations

  • Styles always work with astro dev
  • No errors or warnings are shown during build, regardless if <link> tags are injected or omitted
  • <link> tags are omitted from some generated HTML files, and injected into others
  • The .css files themselves are always generated during astro build (i.e. SiteLogo.vue_vue_type_style_index_0_scoped_true_lang.dbb54b6d.css)
  • Running astro build on my Mac (M1 Pro), about once every 3 builds the <link> tags are omitted from HTML files
  • Running astro build on Netlify, the <link> tags are omitted almost always
  • It doesn't matter if the style tag inside .vue is scoped or not

Sorry, I would love to create a reproducible example. But I can't. I didn't find consistent conditions 😕

Link to Minimal Reproducible Example


@pmochine
Copy link

Have the same issue 🙈

@lhermann
Copy link
Author

lhermann commented May 9, 2022

FYI: I built myself a post-build script as a workaround. Does the job.

import fs from 'fs'
import path from 'path'

fixCssInjections()

function fixCssInjections () {
  const dir = readdirRecursive('dist')
  const cssToInject = dir.filter(file => file.includes('vue_vue_type_style_index_0_scoped_true_lang'))
  const htmlFiles = dir.filter(file => file.endsWith('index.html'))
  for (const htmlFile of htmlFiles) {
    console.info(`Fix CSS injection for ${htmlFile}`)
    injectCss(htmlFile, cssToInject)
  }
}

export function injectCss (file, cssPaths) {
  const contents = fs.readFileSync(file, { encoding: 'utf8', flag:'r' })
  const injectStr = cssPaths.map(cssPath => {
    const relPath = path.relative(file, cssPath)
    return `<link rel="stylesheet" href="${relPath}">`
  })
  const contentParts = contents.split('<head>')
  const newContent = contentParts[0] + '<head>' + injectStr.join('') + contentParts[1]
  fs.writeFileSync(file, newContent, { encoding: 'utf8' })
}

function readdirRecursive (filepath) {
  // Something from stackoverflow 😅
}

@tony-sull
Copy link
Contributor

@lhermann @pmochine Any chance either of you can share a reproduction with a Vue single file component that hits this issue? I definitely want us to dig further into this one to make sure it isn't an issue before 1.0 👍

@tony-sull tony-sull added the needs response Issue needs response from OP label May 10, 2022
@tony-sull tony-sull removed their assignment May 20, 2022
@matthewp matthewp self-assigned this Jun 1, 2022
@FredKSchott FredKSchott assigned tony-sull and unassigned matthewp Jun 1, 2022
@tony-sull
Copy link
Contributor

Closing this out since there isn't a reproduction to dig deeper into, but please open another issue if you manage to reproduce this in one of the astro.new starters and we'll investigate this one further 👍

@vincerubinetti
Copy link

vincerubinetti commented Apr 11, 2023

In my case it's consistently the server.xxxxxxxx.css file that's not being injected into index.html on build, which screws up my entire site.

I'm also using Vue 3 script setup. Also working fine when running dev but breaking during build. Building in static mode.

Packages: astro 2.2.2, @astrojs/vue 2.1.1, vue 3.2.47.

I created this issue: #6827

@HobaiRiku
Copy link

same here, vue3, use SFC file in astro 2.3.0, some component style won't work

@blackspike
Copy link

same for me. rolling back to astro 2.1.3 fixes it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs response Issue needs response from OP
Projects
None yet
Development

No branches or pull requests

8 participants