Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

style cannot load font awesome font file in Angular2SPA #335

Closed
nklt opened this issue Sep 27, 2016 · 10 comments
Closed

style cannot load font awesome font file in Angular2SPA #335

nklt opened this issue Sep 27, 2016 · 10 comments

Comments

@nklt
Copy link

nklt commented Sep 27, 2016

While trying to use one of PrimeNg's sample, in Angular2SPA template, which required to add font-awesome to the Component style's path to load font awesome's CSS file. The URL loader has trouble handling the font file called within one of font awesome's CSS, and showed the following error:

ERROR in ./~/font-awesome/fonts/fontawesome-webfont.eot?v=4.6.3
Module parse failed: C:\workspace10\Angular2Spa\node_modules\font-awesome\fonts\fontawesome-webfont.eot?v=4.6.3 Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.

The sample code is tested in counter.component.ts, and is based on PrimeNg's official sample code.
http://www.primefaces.org/primeng/#/setup

import { Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {AccordionModule} from 'primeng/components/accordion/accordion';
import {MenuItem} from 'primeng/components/common/api';
import {InputTextModule} from 'primeng/primeng';

@Component({
    selector: 'counter',
    styles: [
        require('../../../../node_modules/primeng/resources/themes/omega/theme.css'),
        require('../../../../node_modules/font-awesome/css/font-awesome.min.css'),
        require('../../../../node_modules/primeng/resources/primeng.min.css')],
    template: require('./counter.component.html')
})
export class CounterComponent {
    public currentCount = 0;

    public incrementCounter() {
        this.currentCount++;
    }
}

the WebPack file is modified to use url-loader to handle .eot file, but did not work.

var path = require('path');
var webpack = require('webpack');

var isDevBuild = process.env.ASPNETCORE_ENVIRONMENT === 'Development';

module.exports = {
    devtool: isDevBuild ? 'inline-source-map' : null,
    resolve: { extensions: [ '', '.js', '.ts' ] },
    entry: { main: ['./ClientApp/boot-client.ts'] },
    module: {
        loaders: [
            { test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } },
            { test: /\.html$/, loader: 'raw' },
            { test: /\.css/, loader: 'to-string!css' },
            { test: /\.(eot|woff|woff2|ttf|png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } }
        ]
    },
    output: {
        path: path.join(__dirname, 'wwwroot', 'dist'),
        filename: '[name].js',
        publicPath: '/dist/'
    },
    plugins: [
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./wwwroot/dist/vendor-manifest.json')
        })
    ].concat(isDevBuild ? [] : [
        // Plugins that apply in production builds only
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin()
    ])
};
@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Sep 28, 2016

Can you make sure you're on the latest version of aspnet-webpack (to update it, run npm install aspnet-webpack in your project directory), and also change your require statements to reference the files directly inside the NPM modules like this:

    styles: [
        require('primeng/resources/themes/omega/theme.css'),
        require('font-awesome/css/font-awesome.min.css'),
        require('primeng/resources/primeng.min.css')],

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Sep 28, 2016

Oh wait, I see the issue. Internally, font-awesome refers to its own files with querystrings, e.g.,

src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');

These URLs don't match the regexes you have configured in webpack.config.js (you'd need to change the end-of-string matcher to allow ? to count as an end-of-string too).

The same thing means that the fix for #332 doesn't cover this case. I'll shortly update aspnet-webpack to allow for URLs with querystrings.

UPDATE: aspnet-webpack now correctly handles this case, so please upgrade to the latest version of that.

@tanwarsatya
Copy link

I will suggest using the CDN for the font awesome, that's what I am doing. Also, add this to _layout.cshtml. This is working for me, still i am facing other theme issues when adding those using 'require'

<title>@viewdata["Title"] - AspnetSpa</title>
    <link rel="stylesheet" type="text/css" href="https://github.com//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
</head>
<body>
    @RenderBody()

    @RenderSection("scripts", required: false)
</body>

@tanwarsatya
Copy link

@SteveSandersonMS now with new aspnet-webpack and changing the loaders in webpack.config i don't see any exception. Still components don;t show proper theme, also i checked vender.css but the primeng css are not added to that.
Are we missing something ? I was under assumption that all css will be compiled into vendor.css

@tanwarsatya
Copy link

It would be really helpful if someone can guide how external components can be integrated. A sample is provided for primeng with webpack on (github https://github.com/primefaces/primeng-quickstart-webpack.)
I have successfully integrated the primeng with another template available on github (https://github.com/damienbod/Angular2WebpackVisualStudio)

I am struggling to do the same with template provided by MS team from last 1 week. Thx again for helping with this.

@SteveSandersonMS
Copy link
Member

Although you technically can load 3rd-party vendor CSS scoped to individual Angular 2 components (i.e., by defining styles: [require(...)] on those components), you really shouldn't, because that will pull in an extra copy of the vendor CSS for every component you scope it to. It will make your server-rendered pages large, and your client-rendered pages CPU intensive.

When you integrate with something like PrimeNG or font-awesome, it's much better to put them in your vendor bundle. This is consistent with how PrimeNG's official sample code works: they don't scope the styles to individual components; they load the CSS via a vendor bundle.

Here's an example of a straightforward way of doing that from the latest Angular2Spa template: cff75c6

When copying this implementation into your project, please be sure to update the loaders config in your webpack.config.vendor.js to match those in the branch I linked to. Notice that the test regexes end with (\?|$), not just $, because of how font-awesome refers to its own files using URLs with querystrings.

Also, an important caveat if you plan to use PrimeNG: not all of it is compatible with server-side rendering, because for some of their components, they depend on jQuery and jQuery UI (which don't run inside Node). So you should either disable server-side prerendering, or avoid the PrimeNG components that are incompatible (e.g., the date picker, which really uses jQuery UI), or at least ensure that you only attempt to render the incompatible components when the code is running on the client, not on the server. If this is a problem in your app, you might want to work with the PrimeNG people to remove the jQuery dependency so that their library can be compatible with angular-universal.

@MarkPieszak
Copy link
Contributor

Steve is spot on as always!

As a side note @tanwarsatya I'd suggest using something like ng2bootstrap or Material design, which don't use any jQuery/etc, if server pre-rendering is important to you! They should work without any problems there.

@nklt
Copy link
Author

nklt commented Sep 28, 2016

Hi I have just updated aspnet-webpack to 1.0.16, and assemble the changes in the PrimeNg sample https://github.com/aspnet/JavaScriptServices/commit/cff75c68933ebf6d2737a33f84dcb4076d1fd974 , and I continue to get the webpack error while parsing eot font files.

ERROR in ./~/font-awesome/fonts/fontawesome-webfont.eot?v=4.6.3
Module parse failed: C:\workspace10\Angular2Spa\node_modules\font-awesome\fonts\fontawesome-webfont.eot?v=4.6.3 Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.

Do I do something wrong?

@MarkPieszak
Copy link
Contributor

You need to setup all the needed webpack loaders : [] for all those scenarios (in this case eot files) as well.

{ test: /\.(png|gif|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' },

Take a look at Steves commit here (cff75c6) at things you'll need.

@nklt
Copy link
Author

nklt commented Sep 28, 2016

I re-synchronized the entire project to the head on Sept 28, 2016 and it worked.

0a961a7

Thank you very much.

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

4 participants