TL;DR
- In html use relative paths starting with
assets/...
. In component based CSS use relative paths going one level up: ../assets/...
- Never, and I mean never use asset paths starting with a slash like
/assets
this will break your code in some cases
- Follow the advice below for configuring
karma.conf.js
because karma does not serve assets and currently karma 5.1.1 with webpack 4.44.2 or some plugin of it crashes with OPs error above
Post Mortem (3)
I deleted my first post mortem twice now, because it was broken and lead me to a post mortem (3) :D
Two things are important: You need to tweak the karma.conf.js
as explained in the this SO thread.
Add
proxies: {
'/assets/': '/base/src/assets/'
'/Every-single-image-from-css.png': '/base/src/assets/what-ever-the-path-is/Every-single-image-from-css.png'
},
files: [
{ pattern: './src/assets/**', watched: false, included: false, nocache: false, served: true }
],
in the config.set({
part, and yes, keep /base/src/assets
even if base
is nowhere to be found.
The second part is the file pattern you need to currently make things work with relative paths. The third part is actually the second entry in the proxies
array: List every single resource accessed from css individually :/
Important
ng
preprocesses paths somehow strange, the code above will result in your assets referenced from CSS will be duplicated and lying around in root once ng build
completes. Very ugly but I don't know a solution to this except using images only from html, which gets processed correctly.
The thing I noticed ng serve
flattens all urls. So even a css file looking like this
.my-img{
background: url('../assets/deeply/nested/logo.png');
}
will be served as /logo.png
from the built-in webserver. I checked this while looking at the website produced by ng serve
and inspecting network calls.
What ever this behaviour is, ng test
will die because of this unless you do specify every single image in the proxies part.
Using the first proxies entry, e.g. /assets/
is fun but works only when you would use absolute paths from assets, which you should not but is also used, when you reference images from within html, so keep it!
As the ng compilation flattens the urls, this proxy wont work for css references since even in ng test
the images from css will be requested from root as /logo.png
(stripped of their path). Unfortunately proxies
does not support wildcards, otherwise one could write things like /*.png` to something. But currently listing all entries separately seems to be the solution.
Why using absolute paths in assets is a stupid idea
My first result was to actually recommend to use path like
/assets/foo.png
. Doing this, only the mentioned proxies
entry is necessary (but it had to look a bit different).
Now I thought i was ok, because ng serve
worked, ng test
worked and even ng build
worked.
But things went south when I wanted to deploy my angular app into a subdirectory. If you do this, I was unable to find any way, meddling around with ng build --base-href '..'
and mixing also some --deploy-url
into it to make things work.
When you use absolute paths to your assets, never expect to make things work in a subdirectory.
So you might be lucky using my "broken" approach in some instances but I kid you not, you are very likely to save some time following the excellent advise from @programmerinprogress which I repeated above.