ElMassimo / vite_ruby

⚡️ Vite.js in Ruby, bringing joy to your JavaScript experience
https://vite-ruby.netlify.app/
MIT License
1.28k stars 117 forks source link

Fail to load styles from js files when it conflicts with stylesheet tag #418

Open stoivo opened 10 months ago

stoivo commented 10 months ago

Hi, I am having a issue with loading my styles. I have application.js and application.css. application.css has styles in it and application.js bundles all my javascript. One of my js files import a css file. Vite will output two application-.css files like it should but it will load the same asset twice and the other styles zero times.

I have created a reproduction application. https://github.com/stoivo/demo-rails-vite-issue. When going to the root path the red and blue box should be filled with color.

I did a bit of research myself. Not sure if it's usefull but I want to let you know.

It works differently in with and without the vite devserver.

When requesting the root path while the devserver is running, it look like this.

<!DOCTYPE html>
<html>
  <head>
    <title>ViteApplicationDemo</title>
    <script src="/vite-dev/@vite/client" crossorigin="anonymous" type="module"></script>
    <link rel="stylesheet" href="/vite-dev/entrypoints/application.css" />
    <script src="/vite-dev/entrypoints/application.js" crossorigin="anonymous" type="module"></script>
  </head>

  <body>
    <h1>Post#index</h1>
<p>Find me in app/views/post/index.html.erb</p>

<div class="red-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>
<div class="blue-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>
  </body>
</html>

vite devserver is inlineing the css from appliation.js so it becomes

<html><head>
    <title>ViteApplicationDemo</title>
    <script src="/vite-dev/@vite/client" crossorigin="anonymous" type="module"></script>
    <link rel="stylesheet" href="/vite-dev/entrypoints/application.css">
    <script src="/vite-dev/entrypoints/application.js" crossorigin="anonymous" type="module"></script>
  <style type="text/css" data-vite-dev-id="/Users/simon/Downloads/ViteApplicationDemo/app/javascript/blue.css">.blue-fill{ background: blue; }
</style></head>

  <body>
    <h1>Post#index</h1>
<p>Find me in app/views/post/index.html.erb</p>

<div class="red-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>
<div class="blue-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>
</body></html>

and the red and blue are filled with colors.

When I run rails server without vite I get the following html

<!DOCTYPE html>
<html>
  <head>
    <title>ViteApplicationDemo</title>

    <link rel="stylesheet" href="/vite-dev/assets/application-d6945d36.css" />
    <script src="/vite-dev/assets/application-d2136a89.js" crossorigin="anonymous" type="module"></script>
    <link rel="stylesheet" href="/vite-dev/assets/application-d6945d36.css" media="screen" />
  </head>

  <body>
    <h1>Post#index</h1>
<p>Find me in app/views/post/index.html.erb</p>

<div class="red-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>
<div class="blue-fill" style="height: 100px; width: 100px; border: 5px solid blue;"></div>

  </body>
</html>

As you see it refers to application-d6945d36.css twice. The only the blue box is colored, but not the red

looking at the manifest created

# output from when it it compiling assets
transforming...
✓ 3 modules transformed.
rendering chunks...
computing gzip size...
../../public/vite-dev/manifest-assets.json             0.00 kB │ gzip: 0.02 kB
../../public/vite-dev/manifest.json                    0.34 kB │ gzip: 0.15 kB
../../public/vite-dev/assets/application-69b43dd1.css  0.03 kB │ gzip: 0.05 kB
../../public/vite-dev/assets/application-d6945d36.css  0.03 kB │ gzip: 0.05 kB
../../public/vite-dev/assets/application-d2136a89.js   0.03 kB │ gzip: 0.05 kB
✓ built in 30ms

Build with Vite complete: /Users/simon/Downloads/ViteApplicationDemo/public/vite-dev
# public/vite-dev/manifest-assets.json
{}
# public/vite-dev/manifest.json
{
  "entrypoints/application.css": {
    "file": "assets/application-d6945d36.css",
    "src": "entrypoints/application.css"
  },
  "entrypoints/application.js": {
    "css": [
      "assets/application-d6945d36.css"
    ],
    "file": "assets/application-d2136a89.js",
    "isEntry": true,
    "src": "entrypoints/application.js"
  }
}

What do you think? What can we do about it? If we can't fix it maybe we can raise some error if somebody tries to do this?