I have an app in which I’m trying to load some JS into their own .js files (i.e. bootstrap will be loaded via bootstrap.hash.js
, fontawesome will be fontawesome.hash.js
)
I’m using webpack to do this – but am struggling with fontawesome and their kits specifically (I have a pro subscription). I can load fontawesome via CSS/Fonts no problem – but wanted to use some of the other features available only to JS+SVGs (like layering and masking).
I can load fontawesome pro, it works great. Locally I can have webpack load up the all.min.js
and it puts it in the fontawesome.hash.js
for me – but I need to do that with the kit as it has custom icons that I have added.
This is an example of a working webpack.config.js
that loads fontawesome into it’s own .js
file and puts it in my template:
const autoprefixer = require("autoprefixer");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require("path");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
mode: "production",
entry: {
vendor: "./static/myapp/src/js/vendor.js",
fontawesome: "@fortawesome/fontawesome-pro/js/all.min.js",
main: "./static/myapp/src/js/main.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.join(__dirname, "static/myapp/dist/js/"),
publicPath: "/static/myapp/dist/js/",
},
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin(),
],
splitChunks: {
cacheGroups: {
bootstrapCss: {
name: 'bootstrap',
test: /bootstrap.scss$/,
chunks: 'all',
enforce: true,
},
// fontawesomeCss: {
// name: 'fontawesome',
// test: /fontawesome.scss$/,
// chunks: 'all',
// enforce: true,
// },
fontawesomeJs: {
name: 'fontawesome',
test: /[\/]@fortawesome[\/]fontawesome-pro[\/]js[\/]all.min.js$/,
chunks: 'all',
enforce: true,
},
},
},
},
module: {
rules: [
{
test: /.(scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {sourceMap: true}
},
{
loader: "postcss-loader",
options: {postcssOptions: {plugins: [autoprefixer()]}}
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: ['./static/myapp/src/css'],
},
},
},
],
},
{
test: /.(woff(2)?|ttf|eot|svg)(?v=d+.d+.d+)?$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[name][hash].[ext]',
},
},
],
},
plugins: [
//new BundleAnalyzerPlugin(),
new MiniCssExtractPlugin({
filename: '../css/[name].[contenthash].css',
chunkFilename: '../css/[name].[contenthash].css',
}),
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
template: path.join(
__dirname,
"static/myapp/src/html/webpack_bundles.html"
),
filename: path.join(
__dirname,
"templates/myapp/webpack_bundles.html"
),
// Use our template to control placement of the bundles
inject: false,
chunks: ['bootstrap', 'fontawesome', 'vendor', 'main'],
chunksSortMode: 'manual',
scriptLoading: "blocking",
}),
],
};
Here is a non-working webpack.config.js
where I try to load my kit (which is installed via npm):
const autoprefixer = require("autoprefixer");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require("path");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
mode: "production",
entry: {
vendor: "./static/myapp/src/js/vendor.js",
fontawesome: "@awesome.me/kit-123456abc/icons/js/all.min.js",
main: "./static/myapp/src/js/main.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.join(__dirname, "static/myapp/dist/js/"),
publicPath: "/static/myapp/dist/js/",
},
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin(),
],
splitChunks: {
cacheGroups: {
bootstrapCss: {
name: 'bootstrap',
test: /bootstrap.scss$/,
chunks: 'all',
enforce: true,
},
// fontawesomeCss: {
// name: 'fontawesome',
// test: /fontawesome.scss$/,
// chunks: 'all',
// enforce: true,
// },
fontawesomeJs: {
name: 'fontawesome',
test: /[\/]@awesome.me[\/]kit-123456abc[\/]icons[\/]js[\/]all.min.js$/,
chunks: 'all',
enforce: true,
},
},
},
},
module: {
rules: [
{
test: /.(scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {sourceMap: true}
},
{
loader: "postcss-loader",
options: {postcssOptions: {plugins: [autoprefixer()]}}
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: ['./static/myapp/src/css'],
},
},
},
],
},
{
test: /.(woff(2)?|ttf|eot|svg)(?v=d+.d+.d+)?$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[name][hash].[ext]',
},
},
],
},
plugins: [
//new BundleAnalyzerPlugin(),
new MiniCssExtractPlugin({
filename: '../css/[name].[contenthash].css',
chunkFilename: '../css/[name].[contenthash].css',
}),
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
template: path.join(
__dirname,
"static/myapp/src/html/webpack_bundles.html"
),
filename: path.join(
__dirname,
"templates/myapp/webpack_bundles.html"
),
// Use our template to control placement of the bundles
inject: false,
chunks: ['bootstrap', 'fontawesome', 'vendor', 'main'],
chunksSortMode: 'manual',
scriptLoading: "blocking",
}),
],
};
However that gives me this error:
ERROR in fontawesome
Module not found: Error: Package path ./icons/js/all.min.js is not exported from package /Users/me/project/myapp/node_modules/@awesome.me/kit-123456abc (see exports field in /Users/me/project/myapp/node_modules/@awesome.me/kit-123456abc/package.json)
I can see the file if I open my node_module directory and navigate to it.
If I open the package.json
it says in the error I see these relevant parts:
// Other similar stuff before this
"./icons/sharp/solid": {
"types": "./icons/modules/sharp/solid.d.ts",
"import": "./icons/modules/sharp/solid.mjs",
"require": "./icons/modules/sharp/solid.js",
"default": "./icons/modules/sharp/solid.js"
},
"./icons/sharp/thin": {
"types": "./icons/modules/sharp/thin.d.ts",
"import": "./icons/modules/sharp/thin.mjs",
"require": "./icons/modules/sharp/thin.js",
"default": "./icons/modules/sharp/thin.js"
},
"./icons/kit/custom": {
"types": "./icons/modules/kit/custom.d.ts",
"import": "./icons/modules/kit/custom.mjs",
"require": "./icons/modules/kit/custom.js",
"default": "./icons/modules/kit/custom.js"
},
"./icons/css/*.css": {
"default": "./icons/css/*.css"
},
"./icons/less/*.less": {
"default": "./icons/less/*.less"
},
"./icons/scss/*.scss": {
"default": "./icons/scss/*.scss"
},
// Other stuff after this
So I changed my webpack to include what I thought might be the appropriate thing:
entry: {
// ...
fontawesome: ["@awesome.me/kit-123456abc/icons/classic/solid", "@awesome.me/kit-123456abc/icons/kit/custom"],
// ...
},
It builds the fontawesome.hash.js
file and inserts it into my html – but the file is empty.
The file only contains:
(()=>{"use strict"})();
Any help would be hugely appreciated!