-->

Angular2/Webpack: how to load fonts that are impor

2019-05-10 18:30发布

问题:

I'm using Angular2 beta.15 and webpack 1.12.14.

I have one .css and one .scss file in app.component.ts as global patterns like this.

  @Component({
    selector: 'my-app',
    templateUrl: 'app/app.component.html',
    styles: [
      require('../stylesheets/css/main.min.css'),
      require('../sass/example.scss')
    ],
    encapsulation: ViewEncapsulation.None,
  })

And, inside .css file, some fonts are imported like below,

@font-face {
    font-family: 'Helvetica Neue';
    src: url(fonts/light/helvetica-neue-light.eot) format("eot"), 
         url(fonts/light/helvetica-neue-light.woff2) format("woff2"),   
         url(fonts/light/helvetica-neue-light.woff) format("woff"), 
         url(fonts/light/helvetica-neue-light.ttf) format("truetype");
    font-weight: 300;
    font-style: normal
}

In webpack.config.js, I have loaders for .css, .scss, and fonts like below

  {
    test: /\.scss$/,
    exclude: /node_modules/,
    loaders: ['raw-loader', 'sass-loader'] // sass-loader not scss-loader
  },
  {
       test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/,
       loader: 'url-loader'
  },
  {
    test: /\.css$/,
    loaders: ['style', 'css']
  },

When I ran webpack -display-error-details, there is no error at all, but when I launched the server to run my app, I got error as below

EXCEPTION: Error during instantiation of Token Promise<ComponentRef>!.
ORIGINAL EXCEPTION: Expected 'styles' to be an array of string

If I change the css loader to

  {
    test: /\.css$/,
    loader: 'url-loader'  //or use 'raw-loader'
  },

those exceptions disappeared and the app was start, but I got some 404 requests error for those fonts in browser's console, they're not loaded at all. So, could you give me some pointers? I suspect something wrong in my loader settings.

回答1:

When you chain multiple loaders together, the order of their actions are completed from right to left.

Then the resulting code from the loader is passed to the next one. In this case, you want to chain the raw-loader and url-loader like this to give you the desired result:

loaders: ['raw-loader', 'url-loader']

Since you need to first have your font urls, automatically converted to base64 encoded in the styles, you must first call url-loader in your chain. Then since you are looking to import this file as a module.exports, you call raw-loader.

So in the chain the following happens:

  1. url-loader: Converts all of your url references to static assets into base64:data.
  2. raw-loader: Takes your file, and wraps its entire code with a string and then makes it importable by adding module.exports='string'


回答2:

        Just Try once to keep under one dir both font and css

        // and give the reference onces in webpack.config.rb

         # Set this to the root of your project when deployed:
         http_path = "/"
         css_dir = "app/assets/css"
         sass_dir = "app/assets/sass"


回答3:

try this:

@Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
styles: [
  require('../stylesheets/css/main.min.css').toString(),
  require('!style-loader!css-loader!less-loader!../less/example.less').toString()
]})

I khow the commanand for less, similar command should be available for scss