Skip to content

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

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
JSMike opened this issue Mar 3, 2017 · 24 comments
Assignees

Comments

@JSMike
Copy link
Contributor

JSMike commented Mar 3, 2017

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

@JSMike
Copy link
Contributor Author

JSMike commented Mar 6, 2017

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.

@filipesilva
Copy link
Contributor

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.

@filipesilva
Copy link
Contributor

Searched around and apparently this is just how sass loader works: sass/sass#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.

@JSMike
Copy link
Contributor Author

JSMike commented Mar 15, 2017

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.

@filipesilva
Copy link
Contributor

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

@pmchugh3
Copy link

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.

@jigneshkhokhani
Copy link

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.

@JSMike
Copy link
Contributor Author

JSMike commented Jul 17, 2017

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

@rtm
Copy link

rtm commented Jul 26, 2017

@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?

@JSMike
Copy link
Contributor Author

JSMike commented Jul 27, 2017

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.

@erpardeepjain
Copy link

@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 ?

@thovo
Copy link

thovo commented Dec 7, 2017

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?

@JSMike
Copy link
Contributor Author

JSMike commented Dec 7, 2017

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

@justgeek
Copy link

justgeek commented Jan 6, 2018

Without Modifying Webpack Config, This work:


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

@Jasius
Copy link

Jasius commented Jan 9, 2018

@justgeek works great, thank you.

@ShawnMercado
Copy link

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.

@trsh
Copy link

trsh commented Apr 5, 2018

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

@EugeneSnihovsky
Copy link

EugeneSnihovsky commented May 4, 2018

I spent a day of painful researches and still has this issue. I tried every workaround in this topic and also read
sass/sass#1015
#9185
#3757
#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?

@luispittagros
Copy link

@EugeneSnihovsky Same issue here.

@shuklaniraj
Copy link

same issue...

@yansenlei
Copy link

same issue

@hemregeris
Copy link

Hi,

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

Give a blank between url and (

@semiaddict
Copy link

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

@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 Oct 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests