Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use font-awesome in a Vue app created with vue-cli webpack

I'm trying to use the font-awesome in a simple Vue app created with vue-cli using the webpack-simple template, but this is being tricky.

I installed font-awesome using npm install font-awesome --save and imported it in my entry js (main.js)

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router';
import Home from "./components/Home.vue"

Vue.use(VueRouter);

import 'font-awesome/css/font-awesome.css';

const routes = [
    { path: '/', component: Home }
];

const router = new VueRouter({
    routes,
    mode: 'history'
});

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

This is my current webpack.config.js file:

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

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this nessessary.
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/, 
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      },
      {
        test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url?limit=10000&mimetype=application/font-woff"
      }, {
        test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url?limit=10000&mimetype=application/font-woff"
      }, {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url?limit=10000&mimetype=application/octet-stream"
      }, {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        loader: "file"
      }, {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url?limit=10000&mimetype=image/svg+xml"
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.common.js'
    }
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

I already tried change the font loaders to the following:

{
    test: /\.(png|jpe|jpg|gif|woff|woff2|eot|ttf|svg)(\?.*$|$)/,
    loader: 'file-loader',
    options: {
      name: '[name].[ext]?[hash]'
    }
}

But both configurations throws the same error:

ERROR in ./~/font-awesome/css/font-awesome.css
Module parse failed: /home/james/projects/app/node_modules/font-awesome/css/font-awesome.css Unexpected character '@' (7:0)
You may need an appropriate loader to handle this file type.
| /* FONT PATH
|  * -------------------------- */
| @font-face {
|   font-family: 'FontAwesome';
|   src: url('../fonts/fontawesome-webfont.eot?v=4.7.0');
 @ ./src/main.js 11:0-43
 @ multi main

After some google, I found some links (here, here and here for example), but any of them work for me, the error is always the same.

Whats is the recommended loader to deal with font-awesome files? I think the problem is in the loader, because all regex expressions looks fine to me.

For information, below is the versions in package.json:

"dependencies": {
    "bulma": "^0.3.0",
    "font-awesome": "^4.7.0",
    "vue": "^2.1.0",
    "vue-resource": "^1.0.3",
    "vue-router": "^2.1.1"
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-loader": "^6.0.0",
    "babel-preset-es2015": "^6.0.0",
    "cross-env": "^3.0.0",
    "css-loader": "^0.25.0",
    "file-loader": "^0.9.0",
    "style-loader": "^0.13.1",
    "vue-loader": "^10.0.0",
    "vue-template-compiler": "^2.1.0",
    "webpack": "^2.1.0-beta.25",
    "url-loader": "^0.5.5",
    "webpack-dev-server": "^2.1.0-beta.9"
  }
like image 752
James Avatar asked Jan 08 '17 19:01

James


People also ask

Does Vue CLI use Webpack?

Vue CLI is built on top of Webpack and so for beginners, you do not need to know what Webpack is as the Vue CLI has taken care of the configurations with great default presets and you literally need 0 configs to start.

How do I import Font Awesome into Vue 3?

You can find main. js inside your vuejs 3 project, /src folder. //vue-app/src/main. js import { library } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { fas } from '@fortawesome/free-solid-svg-icons' library.


2 Answers

With the FontAwesome-5 release some exclusive things are done by FontAwesome team for vue and other libraries:

Kinda outdated solution but still works, check the updated solution below:

  • Check fontawesome advance options here
  • For npm package and doc check here

Anyhow, here is what I did to integrate it, first installed these packages:

npm i --save @fortawesome/fontawesome
npm i --save @fortawesome/vue-fontawesome
npm i --save @fortawesome/fontawesome-free-solid

Create a file called fa.config.js and included this code:

import Vue from 'vue';
import fontawesome from '@fortawesome/fontawesome';
import FontAwesomeIcon from '@fortawesome/vue-fontawesome';
import {
  faSpinner,
  faAngleLeft,
  faAngleRight,
} from '@fortawesome/fontawesome-free-solid';

fontawesome.library.add(
  faSpinner,
  faAngleLeft,
  faAngleRight,
);

Vue.component('font-awesome-icon', FontAwesomeIcon); // registered globally

And import it in main.js

import './path/to/fa.config';

And in my components I am using it like this:

<template>
  <div>
    <font-awesome-icon icon="angle-left"></font-awesome-icon> Hey! FA Works
  </div>
</template>

By now you guys might have figured it out what's the advantage of doing as I have done it above?

Using an explicit icon offers the advantage of only bundling the icons that you use in your final bundled file. This allows us to subset Font Awesome's thousands of icons to just the small number that are normally used.

Hope this helps!


UPDATE - Friday, 22 June 2018
The above solution still works but now things are done in different way, first install these packages:

npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons // if "regular" icon package needed
npm i --save @fortawesome/vue-fontawesome

Then create a file called fa.config.js and included this code:

import Vue from 'vue';
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

import { faUser, faBuilding } from '@fortawesome/free-solid-svg-icons'
import { faUserCircle, faCheckCircle } from '@fortawesome/free-regular-svg-icons'

library.add(
  faUser,
  faBuilding,
  faUserCircle,
  faCheckCircle,
);

Vue.component('font-awesome-icon', FontAwesomeIcon); // registered globally

Say that you like you use faUser icon of both the kind regular and solid, then do this change:

import { faUser as fasUser, faBuilding } from '@fortawesome/free-solid-svg-icons'
import { faUser as farUser, faCheckCircle } from '@fortawesome/free-regular-svg-icons'

library.add(
  fasUser,
  farUser,
  faBuilding,
  faCheckCircle,
);

And import it in main.js

import './path/to/fa.config';

And in my components I am using it like this:

<template>
  <div>
    <font-awesome-icon icon="user"></font-awesome-icon>

    // If you like to use Font Awesome Regular, then:
    <font-awesome-icon :icon="['far', 'user']"></font-awesome-icon>
    <font-awesome-icon :icon="['far', 'check-circle']"></font-awesome-icon>

  </div>
</template>
like image 60
Syed Avatar answered Oct 02 '22 01:10

Syed


It seems you need to include a loader for .css in your webpack configuration:

  {
    test: /\.css$/,
    loader: 'css-loader'
  },
like image 22
J. Bruni Avatar answered Oct 02 '22 01:10

J. Bruni