javascript - Vite can't resolve paths from CSS url() - Stack Overflow

admin2025-04-10  0

I have a Vite 4 project that uses vanilla JS & no frameworks. When I reference an asset using CSS url(), it throws a 404 error. The path works fine in HTML img src. I saw the answer for Vue but don't know how it applies to my project without a framework. Merely importing an asset from the index.js file changes nothing.

_search-input.scss

.search-input {
  width: 100%;
  background-image: url("../../assets/icons/search.svg");
}

Index.js:

import "./styles/index.scss"

console.log("index file")

Project structure:

├── src/
│   ├── assets/
│   │   └── icons/
│   │       └── search.svg
│   ├── styles/
│   │   ├── ponents/
│   │   │   └── _search-input.scss
│   │   └── index.scss
│   └── index.js
└── index.html

I removed a single ../ from the path and now the image loads. However, isn't ../assets/icons/search.svg an invalid path? From search-input.scss I'm supposed to go up two levels to get to src/ and then reach assets. My IDE also plains that this path can't be resolved. Why does this work? What is this path relative to?

I have a Vite 4 project that uses vanilla JS & no frameworks. When I reference an asset using CSS url(), it throws a 404 error. The path works fine in HTML img src. I saw the answer for Vue but don't know how it applies to my project without a framework. Merely importing an asset from the index.js file changes nothing.

_search-input.scss

.search-input {
  width: 100%;
  background-image: url("../../assets/icons/search.svg");
}

Index.js:

import "./styles/index.scss"

console.log("index file")

Project structure:

├── src/
│   ├── assets/
│   │   └── icons/
│   │       └── search.svg
│   ├── styles/
│   │   ├── ponents/
│   │   │   └── _search-input.scss
│   │   └── index.scss
│   └── index.js
└── index.html

I removed a single ../ from the path and now the image loads. However, isn't ../assets/icons/search.svg an invalid path? From search-input.scss I'm supposed to go up two levels to get to src/ and then reach assets. My IDE also plains that this path can't be resolved. Why does this work? What is this path relative to?

Share Improve this question edited Jan 24, 2023 at 13:06 semi_92 asked Jan 23, 2023 at 16:42 semi_92semi_92 2776 silver badges15 bronze badges 3
  • Do you know the URL of the image? (The actual, deployed to dev/staging/production/whatever you are testing with, URL?). When the browser resolves teh relative URL you are using, does it match it? What does the Network tab of the browser's developer tools show for the request for that image? – Quentin Commented Jan 23, 2023 at 16:46
  • The URL for requested image is http://localhost:5173/assets/icons/search.svg. When I removed a single ../, the image loaded with the URL http://localhost:5173/src/assets/icons/search.svg. I edited my post, not sure why it works. – semi_92 Commented Jan 23, 2023 at 16:57
  • I just noticed that _search-input.scss is a partial loaded from index.scss file. Could this be issue related to how SASS loads partials and resolves path? – semi_92 Commented Jan 24, 2023 at 13:05
Add a ment  | 

4 Answers 4

Reset to default 1

It is difficult to understand what the problem is without the source code. I had a problem when building projects. I created subdirectories in the dist folder through vite.config for styles, pictures. Used build.rollupOptions.output.assetFileNames. For this reason, paths to images and fonts were not correctly created in css. This is due to the settings of the vite itself.

I searched for a long time how to fix this and found an experimental parameter that helped me solve the problem.

Advanced Base Options

Here is my piece of code that helped me.

With this function, I find the file in which I need to edit the paths and change them. The interface of the function is well described. It is not clear what exactly needs to be returned, but in theory it should be the path to the file.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  base: '',
  plugins: [react()],
  server: {
    open: true,
  },
  build: {
    rollupOptions: {
      output: {
        chunkFileNames: 'assets/js/[name]-[hash].js',
        entryFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: function ({ name }) {
          if (/\.(gif|jpe?g|png|svg)$/.test(name ?? '')) {
            return 'assets/img/[name]-[hash][extname]';
          }

          if (/\.css$/.test(name ?? '')) {
            return 'assets/css/[name]-[hash][extname]';
          }

          if (/.(png|woff|woff2|eot|ttf)/.test(name ?? '')) {
            return 'assets/fonts/[name]-[hash][extname]';
          }
          // default value
          // ref: https://rollupjs/guide/en/#outputassetfilenames
          return 'assets/[name]-[hash][extname]';
        },
      },
    },
  },
  // Функция которая поможет решить проблему путей
  experimental: {
    renderBuiltUrl: function (filename: string, { hostId, hostType, type }: { hostId: string, hostType: 'js' | 'css' | 'html', type: 'public' | 'asset' }) {
      if (type === 'asset') {
        if (hostType === 'css') {
          const stringRemove = 'assets';
          const stringLength = stringRemove.length;
          const stringPesence = filename.indexOf(stringRemove);
          if (-1 !== stringPesence) {
            console.log('..' + filename.substring(stringLength));
            return '..' + filename.substring(stringLength);
          }
        }
      }
    }
  },
})

this worked for me

.app-bg {
  background: url("@/assets/background1.jpg");
  background-size: cover;
}

as I understand it, all paths to image files must be specified relative to the root sass file in which other sass files are piled.

./assets/icons/icon.svg in your case

CSS url() paths are relative to the current css location, in contrast to HTML img src which is not relative to the current path.

Maybe try to add another ../ to your css path.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744275229a239213.html

最新回复(0)