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

Relative path images of SASS @import is not supported #540

Open
jpuncle opened this issue Jan 11, 2018 · 26 comments
Open

Relative path images of SASS @import is not supported #540

jpuncle opened this issue Jan 11, 2018 · 26 comments

Comments

@jpuncle
Copy link

jpuncle commented Jan 11, 2018

Choose one: this is a 🐛 bug report.

💻 Code Sample

main.scss

@import '../components/topbar/index.scss';

topbar/index.scss

.topbar {
  height: 60px;
  background: #f60 url("./play.png") repeat;
  font-size: 2em;
}

🤔 Expected Behavior

main.css

.topbar {
  height: 60px;
  background: #f60 url("md5xxxxxxx.png") repeat;
  font-size: 2em;
}

😯 Current Behavior

main.scss: Cannot resolve dependency './play.png'

🌍 Your Environment

Software Version(s)
Parcel 1.4.1
Node 8.6.0
npm/Yarn npm
Operating System macOS 10.12.6
@jpuncle jpuncle changed the title Relative path images of SASS Relative path images of SASS @import is not supported Jan 11, 2018
@breadadams
Copy link

Seeing the same issue using vue's <style lang="css">...</style> within a .vue component.

@spion
Copy link

spion commented Jan 22, 2018

I have experimental support for relativeUrls for SASS in my fork https://github.com/spion/parcel (by adding "relativeUrls": true in .sassrc. Its really hacky though due to sass/node-sass#2223

Will try submitting a PR once I have tests... but in the meantime, just wondering, anyone has an idea about a better way to do this?

@breadadams
Copy link

breadadams commented Jan 23, 2018

I've been getting around it importing media, ie:

import audio from './song.mp3'
import bgImage from './bg_image.jpg'
import someLogo from './logo.png'

And then inserting those where necessary with js. Not sure if that's of any help @spion

@daoket
Copy link

daoket commented Feb 28, 2018

try this way
import './main.scss' // main.js

@PierBover
Copy link

PierBover commented Apr 12, 2018

I'm having a similar issue with Vue. Not sure if related to this one.

In my main index.scss I can use relative URLs just fine. First import in main.js like this import css from './scss/index.scss'; and then this works:

body {
	background-image: url('../assets/test.jpg');
}

However, when trying to do the same from inside a component I cannot get the image to display from CSS.

So this works when trying to reach the image in the template of the Vue component:

<img src="../assets/test.jpg">

But this doesn't work:

<style lang="scss" scoped>
#App {
	background-image: url('../assets/test.jpg');
}
</style>

And I get this error in the browser:

GET http://localhost:1234/assets/test.jpg 404 (Not Found)

Edit: Sorry for polluting this issue.

I was using parcel-plugin-vue. I removed it and now I'm getting the same problem as @jpuncle with the error Cannot resolve dependency when referencing images from the CSS in the Vue components.

@zhiyan
Copy link

zhiyan commented May 21, 2018

I use *.scss file also produce the same problem, the path of image file can not be found correctly

@petrmiko
Copy link

For less I am using .lessrc file in project root with content

{ relativeUrls: true, }
Until I did that (by trial and error), I faced the same issue with relative path to a image. Maybe the same could help you (if there's something like .sassrc)

@DeMoorJasper
Copy link
Member

DeMoorJasper commented May 24, 2018

I think there isn't really a clean way of achieving this. (After looking through the tracking issue on node-sass and some PRs that should help resolve this)
@spion probably has the currently best solution to this issue, unfortunately.

@dongyuwei
Copy link

@petrmiko thanks .lessrc works for me.

@rambo-panda
Copy link

like #2199

@jussikinnula
Copy link

I created an example stating the issue: https://github.com/jussikinnula/sass-url-issue-with-imports

Basically we would need similar as resolve-url-loader either to be implemented in node-sass or as a postcss plugin. The resolve-url-loader does resolve the url()'s by looking the files defined in source map. You can see the produced source maps for example by doing a node-sass or ruby-sass build.

@DeMoorJasper
Copy link
Member

@jussikinnula there is a fix for the issue (in this branch https://github.com/spion/parcel) although it's kinda hacky. But nobody has implented it in the master yet.
If anyone wants to, feel free to open a PR with this fix.

SASS currently doesn't support this yet, so this is probably the only way to do this.

@jussikinnula
Copy link

@jussikinnula there is a fix for the issue (in this branch https://github.com/spion/parcel) although it's kinda hacky. But nobody has implented it in the master yet.
If anyone wants to, feel free to open a PR with this fix.

SASS currently doesn't support this yet, so this is probably the only way to do this.

Thanks @DeMoorJasper, if I need to use Parcel I'll use that as workaround.

At the moment in project I'm working on I just switched from Parcel to Webpack, and used resolve-url-loader. It's as hacky solution as the one you did. In a sense I like the approach Stylus/LESS have, that there's option to parse relative URLs - so that this kind of hacks are not needed. Definitely fixing SASS would solve the issue with all bundlers (and remove need for resolve-url-loader as well with Webpack).

@DeMoorJasper
Copy link
Member

@jussikinnula I didn't make the fix @spion did, and it's also using a very outdated version of Parcel, so I wouldn't recommend it. I however do recommend someone to make a PR with a similar fix

@devniel
Copy link

devniel commented Mar 3, 2019

Hello, I had a similar problem with this kind of import

@import '../node_modules/@ibm/plex/scss/ibm-plex.scss';,

got solved by wrapping it with url()

@import url('../node_modules/@ibm/plex/scss/ibm-plex.scss');

Thanks!

@lvkins
Copy link

lvkins commented Oct 13, 2019

This doesn't only happens for images.

Recently I tried to setup Font Awesome 5 with web fonts.

// main.scss
$fa-font-path: "../../node_modules/@fortawesome/fontawesome-free/webfonts";
@import "~@fortawesome/fontawesome-free/scss/fontawesome";
@import "~@fortawesome/fontawesome-free/scss/solid";

Fonts are being copied to the output directory root, however Parcel fails to resolve a correct path for them.

I'm really confused about Parcel because anything more than basic setup simply doesn't work: CSS modules and now invalid @import paths 🤔

@github-actions github-actions bot added the Stale Inactive issues label Apr 10, 2020
@lvkins
Copy link

lvkins commented Apr 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.

Don't

@github-actions github-actions bot removed the Stale Inactive issues label Apr 10, 2020
@DeMoorJasper DeMoorJasper added the Stale Ignore This issue is exempt from getting flagged as stale and autoremoved label Apr 10, 2020
@mischnic
Copy link
Member

We would need to process url() before SASS is run (similar to https://github.com/bholloway/resolve-url-loader):

  • either literally do that
  • (or use sourcemaps to find out the original asset of a url statement, but this would break with --no-sourcemaps)

@mischnic mischnic added ✔️ Confirmed Bug CSS Preprocessing All the PostCSS, Less, SASS, etc issues and removed Stale Ignore This issue is exempt from getting flagged as stale and autoremoved labels Apr 11, 2020
@elmuccho
Copy link

elmuccho commented Jan 16, 2022

This method helped me

.classWithUrl {
  background: url('data-url:./background.png');
}

Write inside brackets data-url:

@jameandreu
Copy link

jameandreu commented May 27, 2022

is this issue resolved? I'm having the same problem. I tried @mukhammed3's resolution but that doesn't work for me. I also tried using '~' at the beginning of my url but same issue occurs. The compiled url in my css file by sass is the same as if it was in my home.scss file. Here is my folder structure:

|- css
    styles.css   //background-image:url('./../../src/images/background.png')
    styles.css.map
|- sass
 |-- pages
      home.scss        // background-image:url('./../../src/images/background.png')
|- src
 |-- images
      background.png
index.html  <link rel="stylesheet" href="css/styles.css">

as you can see here my styles.css is referencing the background.png like in my home.scss. It works on my page but when I use Parcel it detects the wrong path of my background.png from my css file.

@lisapps
Copy link

lisapps commented Sep 9, 2022

I'm also having this problem and can't tell from this thread if there's a viable work around? Wanting to use self hosted fonts can't be that unusual.

michelle-may added a commit to michelle-may/michellemay that referenced this issue Sep 30, 2022
@munael
Copy link

munael commented Oct 6, 2022

I'm not even sure what the designed behavior is.

I have a separate compilation step that copies the needed assets to specific locations. I put the correct path in the url('...') but it tries to look for that asset relative to the .scss source directory.

@zeel01
Copy link

zeel01 commented Jun 19, 2023

I'm also running into this issue attempting to import fonts from NPM packages. I can import the SASS file for the font definition, but the paths to the actual font files (woff, ttf, etc) can't be resolved.

@parcel/core: Failed to resolve '../webfonts/fa-regular-400.woff2' from 
'./styles/main.scss'

This is rather frustrating. I can include the pre-built CSS files in my index.html like:

<link rel="stylesheet" href="node_modules/@fortawesome/fontawesome-pro/css/regular.min.css" type="text/css">

But that means I can't do anything to customize the way that file is compiled, such as change $fa-css-prefix or any of the other configurable options this package makes available. And when you include the pre-built CSS file, Parcel has no issue finding those resources and copying them to dist and such, but for SASS it seems to just get lost.

@gavar
Copy link

gavar commented Jul 27, 2023

any updates or workarounds on that? I have the same issue.

@haohuaZhang
Copy link

For less I am using .lessrc file in project root with content

{ relativeUrls: true, } Until I did that (by trial and error), I faced the same issue with relative path to a image. Maybe the same could help you (if there's something like .sassrc)

Thanks!

@zeel01
Copy link

zeel01 commented Oct 6, 2023

I've found a partial work-around for fonts.
If I try to use:

@import "@fontsource/roboto/400.css";

In Sass, this will fail. It will correctly locate the module that I'm referencing, but it will fail to resolve the paths to all the fonts that this stylesheet uses and it will error out as if it were looking for the fonts in the local directory rather than relative to the module.

However, if I do this in CSS:

@import "npm:@fontsource/roboto/400.css";

It works correctly! Furthermore, if I import my CSS file into my Sass file, it also works just fine. So I created a fonts.css file in which I import all the font modules that I am using, and then I import that in my Sass and everything seems to be working.

I'm not entirely sure if this can be utilized to fix issues that others were having with images, but it goes to demonstrate that Parcel is more than capable of doing this correctly, but for some reason is tripping up in the specific case of Sass imports.

I'm assuming that in this case, it works because it's resolving the entire CSS file first before importing it into Sass. This of course doesn't fully fix the issue, but it does at least let all the CSS get bundled into one file now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests