Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Font Awesome & file-loader [hash]

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

We have only one link tag left: FontAwesome:

... lines 1 - 2
<head>
... lines 4 - 10
{% block stylesheets %}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
{% endblock %}
... lines 14 - 15
</head>
... lines 17 - 105

Remove it! And clean up the stylesheets block:

... lines 1 - 2
<head>
... lines 4 - 10
{% block stylesheets %}{% endblock %}
... lines 12 - 13
</head>
... lines 15 - 103

We don't have FontAwesome installed yet... so find your open terminal tab and run:

yarn add font-awesome --dev

That's the name of the official FontAwesome package.

Next, in layout.js, you guys know what to do - add require('font-awesome/'). To get the correct path, once again, open up node_modules/, find font-awesome/, and yes! We can say css/font-awesome.css:

... lines 1 - 8
require('font-awesome/css/font-awesome.css');
require('../css/main.css');
... lines 11 - 15

And without doing anything else, refresh! It works instantly!!! This little icon in the menu is from FontAwesome, and so are a few other icons.

The font-loader Hashed Filenames

Close node_modules/ and look inside web/build/. Wow! It's getting crowded! We have fonts from Bootstrap, fonts from FontAwesome and one image.

And, though it's not really important, but we can't quickly see which files are which... because they all have crazy names.

By default, the filenames are a unique hash based on the contents of the file. That's great, because it means that if you reference two files that have the same name... but usually live in different directories, when they're copied to build/, they won't collide. It's also built-in cache busting! Woo!

Controlling file-loader Hashes

Head back to the Webpack site and click back on "Loading Images". There's a link to the documentation for the file-loader.

It shows how to use the file-loader using the inline syntax, which is one of the reasons I wanted you to see it. It looks like there's an option called name... which should let us control the name of those output files. And, just like with Webpack's output, it has some special placeholders, like [name], [extension] and [hash].

Let's play with this! In webpack.config.js, remove the simple file-loader and use the expanded syntax from earlier. That means, add loader: 'file-loader' and options:

... lines 1 - 3
module.exports = {
... lines 5 - 14
module: {
rules: [
... lines 17 - 33
{
test: /\.(png|jpg|jpeg|gif|ico|svg)$/,
use: [
{
loader: 'file-loader',
options: {
... line 40
},
}
]
},
... lines 45 - 55
]
},
... lines 58 - 63
};

Pass this the name option, set to [name] - that's the original name of the file - -[hash] because we do still want the hash in the name. But shorten it by adding :6. This will only use the first six characters of the hash, which is probably unique enough - these long filenames were bumming me out. Finish with .[ext]:

... lines 1 - 3
module.exports = {
... lines 5 - 14
module: {
rules: [
... lines 17 - 33
{
test: /\.(png|jpg|jpeg|gif|ico|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]-[hash:6].[ext]'
},
}
]
},
... lines 45 - 55
]
},
... lines 58 - 63
};

This is totally not needed - I'm just being anal about how my files are named. Copy all of this and repeat it for the fonts:

... lines 1 - 3
module.exports = {
... lines 5 - 14
module: {
rules: [
... lines 17 - 44
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]-[hash:6].[ext]'
},
}
]
}
]
},
... lines 58 - 63
};

To see this in action, in your terminal, stop webpack, and then clear out the build/ directory:

rm -rf web/build/*

Ok, come back Webpack!

./node_modules/.bin/webpack --watch

Yes! Now, the filenames are way prettier. And I feel better!

Next! Let's get crazy and move our front-end assets... out of the public directory...

Leave a comment!

4
Login or Register to join the conversation
Thao L. Avatar
Thao L. Avatar Thao L. | posted 3 years ago

Font awesome doesn't work anymore, the icons dissapear.

Reply

Hey Thao L.

Hmm, that's odd. Can you tell me what you see if you open the dev tools of your browser and check in the "network" tab for the font-awesome request?

Cheers!

Reply
Default user avatar

"This is totally not needed - I'm just being ---"
I believe there is a small mistake in the transcription. Quite funny mistake, but still... :)

Reply

Hey Ivan,

Haha, let me explain it a bit! :) In English, other than the obvious meaning, "anal" means "to be super uptight about something". So, I could be "anal about testing" if I forced everyone to write 100% test coverage ;)

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial explains the concepts of an old version of Webpack using an old version of Symfony. The most important concepts are still the same, but you should expect significant differences in new versions.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.2.0",
        "symfony/symfony": "3.3.*", // v3.3.16
        "twig/twig": "2.10.*", // v2.10.0
        "doctrine/orm": "^2.5", // v2.7.0
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.5
        "symfony/swiftmailer-bundle": "^2.3", // v2.6.3
        "symfony/monolog-bundle": "^2.8", // v2.12.1
        "symfony/polyfill-apcu": "^1.0", // v1.4.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "friendsofsymfony/user-bundle": "^2.0", // v2.1.2
        "doctrine/doctrine-fixtures-bundle": "~2.3", // v2.4.1
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.3.2
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "friendsofsymfony/jsrouting-bundle": "^1.6" // 1.6.0
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.3.5
    }
}

What JavaScript libraries does this tutorial use?

// package.json
{
    "dependencies": [],
    "devDependencies": {
        "babel-core": "^6.25.0", // 6.25.0
        "babel-loader": "^7.1.1", // 7.1.1
        "babel-plugin-syntax-dynamic-import": "^6.18.0", // 6.18.0
        "babel-preset-env": "^1.6.0", // 1.6.0
        "bootstrap-sass": "^3.3.7", // 3.3.7
        "clean-webpack-plugin": "^0.1.16", // 0.1.16
        "copy-webpack-plugin": "^4.0.1", // 4.0.1
        "core-js": "^2.4.1", // 2.4.1
        "css-loader": "^0.28.4", // 0.28.4
        "extract-text-webpack-plugin": "^3.0.0", // 3.0.0
        "file-loader": "^0.11.2", // 0.11.2
        "font-awesome": "^4.7.0", // 4.7.0
        "jquery": "^3.2.1", // 3.2.1
        "lodash": "^4.17.4", // 4.17.4
        "node-sass": "^4.5.3", // 4.5.3
        "resolve-url-loader": "^2.1.0", // 2.1.0
        "sass-loader": "^6.0.6", // 6.0.6
        "style-loader": "^0.18.2", // 0.18.2
        "sweetalert2": "^6.6.6", // 6.6.6
        "webpack": "^3.4.1", // 3.4.1
        "webpack-chunk-hash": "^0.4.0", // 0.4.0
        "webpack-dev-server": "^2.6.1", // 2.6.1
        "webpack-manifest-plugin": "^1.2.1" // 1.2.1
    }
}
userVoice