Skip to content

No longer able to use relative URL in LESS to reference images in src/assets in beta.32 #4858

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

Closed
LyraelRayne opened this issue Feb 21, 2017 · 16 comments

Comments

@LyraelRayne
Copy link

LyraelRayne commented Feb 21, 2017

Please provide us with the following information:

OS?

OSX Sierra

Versions.

@angular/cli: 1.0.0-beta.32
node: 7.3.0
os: darwin x64
@angular/common: 2.4.8
@angular/compiler: 2.4.8
@angular/core: 2.4.8
@angular/forms: 2.4.8
@angular/http: 2.4.8
@angular/platform-browser: 2.4.8
@angular/platform-browser-dynamic: 2.4.8
@angular/router: 3.4.8
@angular/cli: 1.0.0-beta.32
@angular/compiler-cli: 2.4.8

Repro steps.

  1. ng new test
  2. cd test
  3. ng g component test
  4. mv src/app/test/test.component.css src/app/test/test.component.less
  5. edit src/app/test/test.component.ts to reference the less file instead of css
  6. put an image file (I used sample.svg) into the src/assets folder.
  7. Put the following in src/app/test/test.component.less

.nothing {
background: url("assets/sample.svg");
}

  1. ng build

The log given by the failure.

ERROR in ./src/app/test/test.component.less
Module not found: Error: Can't resolve './assets/sample.svg' in

'/Users/lyrael/test/src/app/test'
@ ./src/app/test/test.component.less 6:60-90
@ ./src/app/test/test.component.ts
@ ./src/app/app.module.ts
@ ./src/main.ts
@ multi ./src/main.ts

Mention any other details that might be useful.

This exact setup worked fine in beta.30 but did not in .32 .

Note that the CSS specifies "assets/sample.svg" but the error says "./assets/sample.svg". I suspect something in the new version is "fixing" (i.e. breaking) my URL path.

@chrste90
Copy link

Hey,

i think this should be fixed in master with #4803

We just need to wait for the next release.

@LyraelRayne
Copy link
Author

I just tried running the master version using the instructions from the github (npm link, etc.) and I still have the same issue when running the steps above.

Version info
@angular/cli: local (v1.0.0-beta.32.3, branch: master)
node: 6.9.4
os: win32 x64
@angular/common: 2.4.8
@angular/compiler: 2.4.8
@angular/core: 2.4.8
@angular/forms: 2.4.8
@angular/http: 2.4.8
@angular/platform-browser: 2.4.8
@angular/platform-browser-dynamic: 2.4.8
@angular/router: 3.4.8
@angular/cli: 1.0.0-beta.32.3
@angular/compiler-cli: 2.4.8

(I ran on windows this time)

@zolekm
Copy link

zolekm commented Feb 21, 2017

+1
I also tried with master and still have same issue, after updating to local assets it works(npm link module used)

@LyraelRayne
Copy link
Author

@zolekm Would you elaborate on what "updating to local assets" means? I'd like to see if I can use this as a workaround.

@zolekm
Copy link

zolekm commented Feb 22, 2017

@LyraelRayne sure, in my angular project i use local modules which are linked in "main project" through node_modules, before my path was "assets/imgs/someimage.jpg"(this was worked before beta.32) then i need to update path to "../../assets/imgs/someimage.jpg". That was in my case i don't know why but now it works for me. In same way for all other assets(fonts etc..) i hope you got the point

@LyraelRayne
Copy link
Author

LyraelRayne commented Feb 22, 2017

Oh I see what you mean. Your use case is slightly different, but what's happening is you're referencing the file path directly from the CSS/LESS file and Webpack is including that file (a second time) as part of the project.

If you look in the dist directory after ng build you'll see that in addition to your assets folder being copied in there, a second copy of your someimage.jpg will be in the root of dist.

This kind of works for me, but it's less than ideal because it means there are duplicates of the resources ( they were in the shared assets folder for a reason, they aren't just used by the CSS). For example in my case, sample.svg is found in both dist/sample.svg and dist/assets/sample.svg with some parts of the application referring to one and the CSS to the other.

You also have to know the path from your LESS file to your resource (meaning directory structure changes will break things).

I'm also not sure whether this would play nicely if there were files with the same name in different subdirectories as the webpack inclusion is flattening these resources to all be in the same directory.

@calebeaires
Copy link

I had the same issue; for now, I just remove ./ and put / before declare path

background: url('/assets/img/others/bg-drop-here-big.png') no-repeat center center;

@zolekm
Copy link

zolekm commented Feb 24, 2017

@calebeaires @LyraelRayne with my approach i don't have issue anymore so i suggest to just fix path to assets and it should work

@LyraelRayne
Copy link
Author

That doesn't fix the issue, it replaces the relative path with a root relative path. Fine if your webapp is going to run in the root, but mine isn't. That's why I'm not using root relative paths in the first place. The app gets deployed in a number of different paths so I don't know what the root will be at compile time.

@stephanrauh
Copy link

stephanrauh commented Feb 28, 2017

@LyraelRayne AFAIK, Angular replaces the root relative paths when loading the application by paths relative to what's defined in the index.html:

  <base href="/my/context/name">

@LyraelRayne
Copy link
Author

@stephanrauh Not quite. That base href is what tells the browser where to start plain old relative URLs ("folder/something.svg". Which is what I'm using in my existing application to deal with the fact that I don't know the root. That's working fine. What's not working fine is that Webpack/LESS is now telling me that I'm not allowed to do that because it can't find the file at compile time (Webpack wants to find the file and package it for me, but doesn't know to look in the src/assets folder).

Webpack ignores root relative paths ("/root/folder/something.svg") in CSS because otherwise it wouldn't know what to do with them. In older versions of CLI it would ignore relative paths in CSS because it wasn't configured to do anything with them.

@LyraelRayne
Copy link
Author

@filipesilva Would you be able to weigh in on this. You seem to be active in this space.

I suspect that what I want to do is no longer possible with current versions of CLI.

In short what I need is the ability to create a component CSS which in the output contains a relative path (assets/image.svg).

The reason is because I deploy the web application to multiple locations (http://www.site1.com/site1 and http://www.site2.com/site2). I could do the build N times (one per root) with different --deploy-urls, but that multiplies the build time by N so I'd rather avoid if possible as it already takes a minute or so to do it once.

@filipesilva
Copy link
Contributor

Heya, this issue is mostly a dupe of #4778.

@clydin's comment (#4778 (comment)) and mine (#4778 (comment)) should help shed some light on the topic, and the issue at the time was fixed by #4803.

@LyraelRayne the TLDR is that if you use absolute paths, you will get an absolute path composed (with resolved --base-href and --deploy-url). This doesn't seem to be what you need since you deploy the same thing to different places. Instead you seem to need a relative path, resolved from your page's current path.

I'm sorry this behaviour changed and that it affected your usecase, but it does open to door to better compile time checks and further image processing/optimizations so I think it's an overall better model. Mind you that global CSS always did this, it was broken in component CSS only, and that the inconsistency was also a bad thing.

@LyraelRayne
Copy link
Author

Thanks @filipesilva . From reading other issues I suspected this might have been the case. I agree that the change is for the better as it solves a bunch of other problems and makes things consistent.

Would it be possible to re-open this as a feature request whereby the assets directory specifically could be referenced by CSS using some kind of prefix (like @assets/path/something.svg). Referencing assets from CSS seems like it'd be a common use case so it'd be great if it can be accommodated. Otherwise I guess I'll invoke the almighty Hax and postprocess my CSS.

Feel free to tell me to submit a separate issue as a feature request if you feel that is more appropriate, I just wanted to avoid making Yet Another Duplicate Issue.

@filipesilva
Copy link
Contributor

I don't think the assets dir should be specialcased per se as it's a configurable one - and generally putting images there also means they would both be included and copied over.

You should open an issue though. It's a valid point that doing a long relative path (../../../../../assets/image.png) gets old fast. I can't promise it's somethat that will be actioned anytime soon though, but it's better to have the issue request for people to discuss.

We did something similar to help with import paths, by leveraging the include functionality of sass/stylus (less doesn't have it): #4003. It might even work for images, but I haven't tested it myself.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants