import assets issue, electron forge

Viewed 1078

I'm currently trying to build an electron app. I am trying to introduce a custom font into my application and in development, the custom font works, however, when it's compiled into a production-ready app the font doesn't pull through.

I have placed a 'bare bones' application here to highlight the issue, https://github.com/jacobluke121/electron-forge-font-issue-. I have also included the relevant code here.

I'm under the impression the issue will be around my Webpack configuration. Inside the webpack.renderer.config.js I using the copy-webpack-plugin to move my assets from my static folder into the .webpack/renderer folder. The assets do move over into production, however, when compiled it says they cannot be found in the developer console by the renderer, even though they are clearly in the resource tab in the developer console.

The files included below aren't all the files for the project, but I feel they are most relevant to my issue.

main.js aka electron side

const {app, BrowserWindow} = require('electron');
const electronLog = require('electron-log');

const main_log = electronLog.create('main')
//set console.log to main_log.log,
console.log = main_log.log;


let mainWindow;

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
    app.quit();
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', (event) => {
    event.preventDefault();
    mainWindow = new BrowserWindow({
                                       width: 1280, height: 960,
                                       webPreferences: {
                                           nodeIntegration: false,
                                           webSecurity: false,
                                           contextIsolation: true,
                                           enableRemoteModule: false,
                                           preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
                                       }
                                   });

    mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);


    mainWindow.webContents.openDevTools();


    // if closed then end application:
    mainWindow.on('closed', function () {
        main_log.info('%c Closing. %c The application', 'color: red', 'color: green');
        mainWindow = null;
    });
});

// Quit when all windows are closed.
app.on('window-all-closed', () => {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    // On Mac OS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) {

        mainWindow = new BrowserWindow({
                                           width: 1280,
                                           height: 960,
                                       });
        mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
    }
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.jsx

import React, {Component} from 'react';
import './app.css';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {

    render() {
        return (
            <div>
                <p className="san-serif">This is supposed to be Calibril Light in Production but it's not...</p>
                <p className="san-serif">however, when you run 'yarn start' its the correct font-family</p>
                <p className="san-serif">When in production if you look in the dev console tools, you can see that the font family is there under resources...</p>
            </div>)
    }
}

export default App;

app.css

@font-face {
  font-family: "Calibri Light2";
  font-style: normal;
  font-weight: normal;
  src: url("/fonts/calibril.woff") format("woff");
}
.san-serif {
  font-family: "Calibri Light2";
}

/*# sourceMappingURL=app.css.map */

webpack.main.config.js

module.exports = {
  /**
   * This is the main entry point for your application, it's the first file
   * that runs in the main process.
   */
  entry: './src/electron/main.js',
  // Put your normal webpack config below here
  module: {
    rules: require('./webpack.rules'),
  },
  resolve: {
    extensions: ['.js', '.jsx', '.css', '.woff']
  },
};

webpack.renderer.config.js

const rules = require('./webpack.rules');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const assets = ["fonts"]

module.exports = {
    // Put your normal webpack config below here
    module: {
        rules,
    },
    resolve: {
        extensions: ['.js', '.jsx', '.css', '.woff'],
    },
    plugins: assets.map(asset => {
        return new CopyWebpackPlugin({
                                         patterns : [
                                             {
                                                 from: path.resolve(__dirname, 'static', asset),
                                                 to: path.resolve(__dirname, '.webpack/renderer', asset)
                                             }
                                             ]
                                     });
    }),
}

webpack.rules.js

const path = require('path');

module.exports = [
    // Add support for native node modules
    {
        test: /\.node$/,
        use: 'node-loader',
    },
    {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules|.webpack)/,
        loaders: [{
            loader: 'babel-loader'
        }]
    },
    {
        test: /\.css$/,
        use: [{loader: 'style-loader'}, {loader: 'css-loader'}],
    },
    {
        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
            {
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]',
                    outputPath: 'fonts/'
                }
            }
        ]
    },
]

I would greatly appreciate your help with this, if I can't get this working, I'll have to use another packager for electron.

Thanks for your help.

1 Answers

I was facing same issue today after many hit and trials only adding this in rules worked for me without using any extra plugin

{
    test: /\.(ttf|otf|eot|svg|woff2|woff)$/,
    use: [
        {
            loader: "file-loader",
            options: {
                name: "[path][name].[ext]",
                publicPath: "../",
            },
        },
    ],
}

in electron-forge v6.0.0 with webpack plugin

Related