Angular-cli: SCSS "Module not found: Error: Can't resolve" for @font-face url with relative path

Created on 3 Mar 2017  Â·  24Comments  Â·  Source: angular/angular-cli

Please provide us with the following information:

OS?

Linux (Docker hub image: mhart/alpine-node:6.9.4) on OSX host

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here:

    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / â–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/

@angular/cli: 1.0.0-rc.1
node: 6.9.4
os: linux x64

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

Importing a font with sass using relative path:

@font-face {
  font-family: 'Gotham-Light';
  src: url('../fonts/Gotham-Light.eot?#iefix') format('embedded-opentype'),  
    url('../fonts/Gotham-Light.otf')  format('opentype'),
    url('../fonts/Gotham-Light.woff') format('woff'), 
    url('../fonts/Gotham-Light.ttf')  format('truetype'),
    url('../fonts/Gotham-Light.svg#Gotham-Light') format('svg');
  font-weight: normal;
  font-style: normal;
  line-height: 1.5;
}

The log given by the failure.

Normally this include a stack trace and some more information.

ERROR in ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader!./~/sass-loader!./src/styles.scss
Module not found: Error: Can't resolve '../fonts/Gotham-Light.eot' in '/code/src'
 @ ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader!./~/sass-loader!./src/styles.scss 6:108-144
 @ ./src/styles.scss
 @ multi ./~/material-design-icons/iconfont/material-icons.css

Mention any other details that might be useful.

Looks like this may be related to https://github.com/angular/angular-cli/issues/4778

From my understanding relatives paths in url() was fixed for @import, maybe something additional needs to be done for @font-face

Also, this error doesn't occur when using the absolute path starting from src/, the error only appears when using the relative path.


Thanks! We'll be in touch soon.

help wanted

Most helpful comment

Searched around and apparently this is just how sass loader works: https://github.com/sass/sass/issues/1015

There's a suggestion for using https://github.com/bholloway/resolve-url-loader, but it does have the serious limitation of not working without sourcemaps. This is a big problem because component css doesn't support sourcemaps at all, and your project shouldn't die just because sourcemaps aren't there.

So I think the recommended approach here is to put these font files in the assets folder, and use absolute paths (starting with /) for urls in sass files that are imported by other sass files.

@font-face {
  font-family: 'Gotham-Light';
  src: url('/assets/fonts/Gotham-Light.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  line-height: 1.5;
}

If anyone has a better way I'm happy to hear it.

All 24 comments

I've created an example repository for this issue: https://github.com/JSMike/angular-cli-issue-5213

The result is:

ERROR in ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader!./~/sass-loader!./src/styles.scss
Module not found: Error: Can't resolve '../fonts/Gotham-Light.otf' in '/code/src'
 @ ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader!./~/sass-loader!./src/styles.scss 6:168-204
 @ ./src/styles.scss
 @ multi ./src/styles.scss
webpack: Failed to compile.

Hm I'm looking at your example repo and as far as I can tell what's happening is that the font is always being resolved relative to the initial entry point (styles.scss).

So if I change it url('app/lib/fonts/Gotham-Light.otf') it works.

This looks like a bug somewhere really.

Searched around and apparently this is just how sass loader works: https://github.com/sass/sass/issues/1015

There's a suggestion for using https://github.com/bholloway/resolve-url-loader, but it does have the serious limitation of not working without sourcemaps. This is a big problem because component css doesn't support sourcemaps at all, and your project shouldn't die just because sourcemaps aren't there.

So I think the recommended approach here is to put these font files in the assets folder, and use absolute paths (starting with /) for urls in sass files that are imported by other sass files.

@font-face {
  font-family: 'Gotham-Light';
  src: url('/assets/fonts/Gotham-Light.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  line-height: 1.5;
}

If anyone has a better way I'm happy to hear it.

My solution for now was to create css instead of scss files for importing fonts from relative paths, and add the import of the css file into src/styles.scss.

I'm closing it as 'working as intended' as per sass then.

It seems to me this does not "work as intended". You need to provide a way for libraries with relative scss imports to work, given that webpack projects can do this. Otherwise we have to try hack a workaround, ditch the scss library or remove angular-cli.

In fresh app when I ran npm install or npm install --save and then run ng s then it gives me error like below. I think because of package-lock.json file is not generated for me in fresh app after running npm install.

ERROR in ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader?{"ident":"postcss"}!./~/sass-loader/lib/loader.js?{"sourceMap":false,"precision":8,"includePaths":[]}!./src/styles.scss
Module build failed: Error: ENOENT: no such file or directory, scandir '/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/vendor'
    at Object.fs.readdirSync (fs.js:914:18)
    at Object.getInstalledBinaries (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/extensions.js:124:13)
    at foundBinariesList (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:20:15)
    at foundBinaries (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:15:5)
    at Object.module.exports.missingBinary (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:45:5)
    at module.exports (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/binding.js:15:30)
    at Object.<anonymous> (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/index.js:14:35)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/sass-loader/lib/loader.js:3:14)
    at Module._compile (module.js:571:32)
 @ ./src/styles.scss 4:14-189
 @ multi ./src/styles.scss

ERROR in ./src/app/app.component.scss
Module build failed: Error: ENOENT: no such file or directory, scandir '/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/vendor'
    at Object.fs.readdirSync (fs.js:914:18)
    at Object.getInstalledBinaries (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/extensions.js:124:13)
    at foundBinariesList (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:20:15)
    at foundBinaries (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:15:5)
    at Object.module.exports.missingBinary (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/errors.js:45:5)
    at module.exports (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/binding.js:15:30)
    at Object.<anonymous> (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/node-sass/lib/index.js:14:35)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/jigneshkhokhani/sites/workspace/fitness/node_modules/sass-loader/lib/loader.js:3:14)
    at Module._compile (module.js:571:32)
 @ ./src/app/app.component.ts 18:17-48
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://localhost:4200 ./src/main.ts

But after that I switch finally to yarn and it working like charm :)
yarn install generate yarn.lock file and it resolved my issue.

@jigneshkhokhani your issue is unrelated to this item. Please look for a similar issue or create a new one.

@This is still not working for me. I serve my app from a subdirectory, as in http://myserver.com/subdir. I have set outDir and <base> correctly and the app runs fine. However, fonts referred to by URLs in @font-face directories, when specified as /assets/fonts/... do not load, because it tries to load them from http://myserver.com/assets/fonts instead of http://myserver.com/subdir/assets/fonts. If I specify the URL as assets/fonts or ./assets/fonts, then I get a build error

Module not found: Error: Can't resolve './assets/fonts/tf-icon-font.eot' in '/home/rtm/repos/TNF/identity-ui/src'

So I am stuck. I tried moving the @font-face directives into a CSS file, and including that in the styles property of angular-cli.json, but ended up with almost exactly the same problem. I finally put them directly in a <style> tag in my index.html, and that works, but certainly there must be a better way?

If you're using the CLI then webpack will take care of the font bundling, it doesn't need to be in assets. Your CSS file @fontface should just have the relative path to the fonts in your local file system, you can have a separate fonts folder outside of src if you want.

@filipesilva you are right, but thing is while deploy code on server it is again showing "no module found"

so i have tried using /assets to assets but not working any idea ?

I met the same problem but not on local anymore, it happened at server. In scss file, if I followed the same instructions as @filipesilva it worked normally on local. But when I used the ng build to have the production file, it kept the same path and cause an errors font not exist. @JSMike I think I will try with yours. Is there any other solution we can do here?

@thovo the file with the @fontface should be a css file, not a scss file. see if that helps. Then in your scss just import the css file. Webpack should take care of the rest.

Without Modifying Webpack Config, This work:


$mdi-font-path: '~mdi/fonts/';
@import '~mdi/scss/materialdesignicons';

@justgeek works great, thank you.

Maybe I'm confused, but importing as raw css does not solve the problem for anyone who wants to import an external stylesheet as a sass file so that they can @extend or @include something in it, if that stylesheet contains relative urls.

@ShawnMercado same here.

I bought one Theme, that is used as npm module, and has lots of xxx/xxx.png paths. All those give me errors, and CLI is useless. Copying something doesn't help, as I have rename all URL paths to absolutes. If I do that I will have problems with updating my theme. This is big problem.

I spent a day of painful researches and still has this issue. I tried every workaround in this topic and also read
https://github.com/sass/sass/issues/1015
https://github.com/angular/angular-cli/issues/9185
https://github.com/angular/angular-cli/issues/3757
https://github.com/angular/angular-cli/issues/2403

On local machine (OS X 10.13.3) all works fine, but on gitlab runner (ubuntu image) command ng build --prod fail with error

  102 | @font-face {
  103 |   font-family: "SFUIText-Bold";
> 104 |   src: url("../assets/fonts/SFUI/SFUIText-Bold.otf");
      |             ^
  105 |   font-style: normal;
  106 |   font-weight: normal;

also try

src: url("/assets/fonts/SFUI/SFUIText-Bold.otf");

also try to switch from scss to css and import it
and with this version app build without error, but when I launch it I see 404 for this font.

How can I solve this?

@EugeneSnihovsky Same issue here.

same issue...

same issue

Hi,

Just use url ('/assets/ instead of url('/assets/

Give a blank between url and (

@hemregeris, I had the same issue in a non angular related project using webpack, and this seems to work.
Could you explain why we need a space between url and ( ?
Thank you.

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._

Was this page helpful?
0 / 5 - 0 ratings