Automatically detect and import fontawesome icons used in your webapp π
This package aims to be framework (like React or Vue.js) agnostic. However, I have only tested it using webpack/VueJS.
π Feel free to open a PR with example/documentation for other use case!
It implements simple parsing techniques that would generate a file that imports all used icons without having to manage them every single time:
- parse your
package.json
file to detect which font awesome styles are available in your project - parse any
.vue
and.js
files in yoursrc
folder naively looking for fontawesome icon definitions (must by an array with explicit prefix) - generate the "import" file in
src/plugins/fontawesome-autoimport.js
(only if needed - aka icon added/removed in project π)
The parsing could be made manually or automatically, depending of your needs.
$ yarn add -D @onedrynugget/fontawesome-autoimport
$ npm install --save-dev @onedrynugget/fontawesome-autoimport
- Make sure your source code exists within the
src
folder of the project's main directory. - Make sure you have installed appropriated fontawesome official plugin (vue-fontawesome, react-fontawesome...)
Add these definitions to your entry point such as your main.js
file
// Import autogenerated fontawesome imports
import "@/plugins/fontawesome-autoimport.js";
// Import regular fontawesome component
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
Vue.component("FontAwesomeIcon", FontAwesomeIcon);
Add these definitions to your entry point such as your index.js
file
// Import autogenerated fontawesome imports
import "./plugins/fontawesome-autoimport.js";
The usage is almost identical to how you would normally use the official plugin except that you can't use the Shorthand that assumes a prefix of "fas", such as:
<font-awesome-icon icon="video" />
instead, you would just have to write the following:
<font-awesome-icon :icon="['fas', 'video']" />
The usage is almost identical to how you would normally use the official plugin except that you can't use the Shorthand that assumes a prefix of "fas", such as:
<FontAwesomeIcon icon="video" />
<FontAwesomeIcon icon={faVideo} />
instead, you would just have to write the following:
<FontAwesomeIcon icon={["fas", "video"]} />
There's basically two ways to do this, either manually or automatically.
Note: This tool will prioritize the pro versions of the installed svg icons set, so if for instance you have both free-solid-svg-icons
and pro-solid-svg-icons
, then the tool will use the pro one, otherwise the free one.
Executing the following npm command would run the script:
$ npm explore @onedrynugget/fontawesome-autoimport -- npm run gen
And you should see the success output message such as:
- Fontawesome treeshaking list generated. (took 10 ms)
This is achieved by hooking into webpack's events, so an additonal library is required, in our case, we'll be using before-build-webpack
$ npm install --save-dev before-build-webpack
Configure webpack (via vue.config.js
or alternative) like this:
var WebpackBeforeBuildPlugin = require('before-build-webpack');
// ...
module: {
plugins: [
new WebpackBeforeBuildPlugin(function(stats, callback) {
const {execSync} = require('child_process');
console.log(execSync('npm explore @onedrynugget/fontawesome-autoimport -- npm run gen').toString());
callback();
}, ['run', 'watchRun'])
]
},
// ...
then build the project as you normally would:
$ yarn build
or
$ npm run build
The output of build should include the following line
- Fontawesome treeshaking list generated. (took 10 ms)
When using "create react app" scripts, the webpack config is handled by react-scripts
.
And so we can't directly update it except by using the "eject" provided command.
However most dev don't want to take care of webpack config manually.
Fortunatly, there is Craco π
Once Craco is installed in your webapp, add the following in craco.config.js
:
var WebpackBeforeBuildPlugin = require("before-build-webpack");
module.exports = {
webpack: {
plugins: {
add: [
new WebpackBeforeBuildPlugin(
function(stats, callback) {
const { execSync } = require("child_process");
console.log(
execSync(
"npm explore @onedrynugget/fontawesome-autoimport -- npm run gen"
).toString()
);
callback();
},
["run", "watchRun"]
)
]
}
}
};
then build the project as you normally would:
$ yarn build
or
$ npm run build
The output of build should include the following line
- Fontawesome treeshaking list generated. (took 10 ms)
Once the script has finished executing, it should produce a file at src/plugins/fontawesome-autoimport.js which its content would look like the following:
// Generated by fontawesome-autoimport
// fas
import {
faCircle as fasCircle,
faAngleDown as fasAngleDown,
faBars as fasBars
} from "@fortawesome/pro-solid-svg-icons";
// far
import {
faSignOutAlt as farSignOutAlt,
faComments as farComments
} from "@fortawesome/pro-regular-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";
library.add(fasCircle, fasAngleDown, farSignOutAlt, fasBars, farComments);
Sometimes you may want to customize the pattern used to match fontawesome icons in your projet.
It may happens if you have written a wrapper around the regular vue-fontawesome
provided component (aka FontAwesomeIcon
).
Wrapper example (Fa.vue
):
<template>
<FontAwesomeIcon :icon="faIcon" v-bind="$attrs" v-on="$listeners" />
</template>
<script>
export default {
props: { icon: { type: String, required: true } },
computed: {
faIcon: ({ icon }) => {
const [, style, name] = icon.match(/(fa[a-z])-([a-z-]+)/);
return [style, name];
}
}
};
</script>
In that situation, a fontawesome icon will looks like <fa icon="fas-check" />
(html) or const icon = 'fas-check'
(js).
To handle that custom syntaxe, you can pass a custom pattern as env variable like this:
pattern="['\"](fa[a-z])-([a-z-]+)['\"]" npm explore @onedrynugget/fontawesome-autoimport -- npm run gen
or (for the automated version):
var WebpackBeforeBuildPlugin = require('before-build-webpack');
// ...
module: {
plugins: [
new WebpackBeforeBuildPlugin(function(stats, callback) {
const {execSync} = require('child_process');
console.log(execSync(
'npm explore @onedrynugget/fontawesome-autoimport -- npm run gen',
{ env: { pattern: `['"](fa[a-z])-([a-z-]+)['"]` } }
).toString());
callback();
}, ['run', 'watchRun'])
]
},
// ...
This project is eavily inspired by @GTANAdam vue-fontawesome-autogen. In fact, the initial release of this project was proposed in a pull request as a complete rewrite of vue-fontawesome-autogen. Unfortunatly @GTANAdam is deeply attached to a custom syntaxe and using the customization provided in this package means a "breaking change" which seems too complicated in his projects. After a lot of discussion, I finally decided to go ahead and publish my own project.
- Require by far less change to be used in an existing projet (only have to explicit the usage of
fas
style) - Take care of icons defined in
.js
files (useful for generated list based on an array/object/whatever imported from a.js
file) - Handle webpack
watchRun
mode - Should be compatible with any futur font awesome style (no hard-coded list anymore) π€
- Hint the developer about unknown icon (probably caused by forgotten style installation)
- About 50% faster (well, the original one is probably fast enough, but still π)
- Less code (less bug )