FTW
FTW

Reputation: 1022

Use font-face with webpack encore

So I'm working on a symfony 4 project, and since I have no choice, I'm using webpack encore. In my css, I'm trying to use a font, imported with font-face.

So I have :

assets/css/app.css:

...
@font-face 
{
    font-family: "myfont";
    src: url('build/fonts/myfont.eot'); /* IE9 Compat Modes */
    src: url('build/fonts/myfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
         url('build/fonts/myfont.woff') format('woff'), /* Modern Browsers */
         url('build/fonts/myfont.ttf')  format('truetype'), /* Safari, Android, iOS */
         url('build/fonts/myfont.svg#myfont') format('svg'); /* Legacy iOS */
}
...

my fonts are in assets/fonts/

I tried differents paths / ways and got differents error messages, the current one being :

These relative modules were not found:

Please note that I want to keep it simple, not downloading something that should not be needed to do such a simple stuff.

So my question is : what is THE official / basic way to do it (which path in the font-face, and which config if needed) ? I searched for several days but nothing I found was working or applicable to my case, this is particularly frustrating knowing that it should be super easy.

My webpack.config.js is the default one, unmodified :

var Encore = require('@symfony/webpack-encore');

Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')

/*
 * ENTRY CONFIG
 *
 * Add 1 entry for each "page" of your app
 * (including one that's included on every page - e.g. "app")
 *
 * Each entry will result in one JavaScript file (e.g. app.js)
 * and one CSS file (e.g. app.css) if you JavaScript imports CSS.
 */
.addEntry('app', './assets/js/app.js')
.addEntry('index', './assets/js/index.js')
//.addEntry('page2', './assets/js/page2.js')

/*
 * FEATURE CONFIG
 *
 * Enable & configure other features below. For a full
 * list of features, see:
 * https://symfony.com/doc/current/frontend.html#adding-more-features
 */
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())

// enables Sass/SCSS support
//.enableSassLoader()

// uncomment if you use TypeScript
//.enableTypeScriptLoader()

// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

Thank you

Upvotes: 5

Views: 8782

Answers (2)

FTW
FTW

Reputation: 1022

I gave up doing it without plugins or loader, I tried the file loader : didn't work, I tried the copy plugin : success.

webpack.config.js

var Encore = require('@symfony/webpack-encore');

var CopyWebpackPlugin = require('copy-webpack-plugin');

Encore
    ...
    .addPlugin(new CopyWebpackPlugin([
        { from: './assets/fonts', to: 'fonts' }
    ]))
    /*.addLoader({
        test: /\.(eot|svg|ttf|woff)$/,
        use: [{
            loader: 'file-loader',
            options: {
                name: '[path][name].[ext]',
                context: './assets',
            }
        }]
    })*/

    ...
;

module.exports = Encore.getWebpackConfig();

the css:

@font-face 
{
    font-family: "myfont";
    src: url('/build/fonts/myfont.eot'); /* IE9 Compat Modes */
    src: url('/build/fonts/myfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
         url('/build/fonts/myfont.woff') format('woff'), /* Modern Browsers */
         url('/build/fonts/myfont.ttf')  format('truetype'), /* Safari, Android, iOS */
         url('/build/fonts/myfont.svg#myfont') format('svg'); /* Legacy iOS */
}

Update for new versions of webpack encore : This answer wasn't working anymore after updating webpack encore.

Now, I could remove the CopyWebpackPlugin, and could instead refer to the fonts in the assets folder (webpack detects the urls and copy them in the build, and change the path all alone)

The CSS:

@font-face 
{
    font-family: "myfont";
    src: url('../fonts/myfont.eot'); /* IE9 Compat Modes */
    src: url('../fonts/myfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
         url('../fonts/myfont.woff') format('woff'), /* Modern Browsers */
         url('../fonts/myfont.ttf')  format('truetype'), /* Safari, Android, iOS */
         url('../fonts/myfont.svg#myfont') format('svg'); /* Legacy iOS */
}

Note that the svg version is put by webpack in an image folder, not font.

Upvotes: 6

Fabian Schmick
Fabian Schmick

Reputation: 1654

Another approach would to change how the font-files get saved. You can read more here https://github.com/symfony/webpack-encore/issues/282

Encore
    .addLoader({
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
            {
                loader: 'file-loader',
                options: {
                    outputPath: 'assets/dist/fonts/''
                }
            }
        ]
    })
    .configureFilenames({
        fonts: 'fonts/[name].[ext]'
    })

Upvotes: 2

Related Questions