Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/icons-to-woff.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@ module.exports = function createIconFont (fs, icons, options) {
icons = icons.map((iconPath) => path.resolve('.', iconPath));
return new Promise((resolve, reject) => {
const fontStream = new Svgicons2svgfont({
name: options.name,
fontName: options.name,
normalize: true,
fontHeight: options.enforcedSvgHeight ? options.enforcedSvgHeight : undefined,
log: function () {},
error: /** @param {any} err */function (err) {
reject(err);
}
log: function () {}
});
let svgFont = '';
fontStream
Expand Down
3 changes: 1 addition & 2 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* 'module.exports="data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAQwAA..";
*/
const createIconFont = require('./icons-to-woff.js');
const loaderUtils = require('loader-utils');
const path = require('path');

module.exports = function () {
Expand All @@ -19,7 +18,7 @@ module.exports = function () {
// The query is built in postcss-plugin.js in addFontDeclaration
// it contains the following values:
// { svgs: resolvedRelativeSvgs, name: fontName };
const query = loaderUtils.parseQuery(this.query);
const query = this.getOptions();
// Add svgs to webpack file watching:
query.svgs.forEach((svg) => this.addDependency(path.resolve(svg)));
// Generate the fonts
Expand Down
71 changes: 40 additions & 31 deletions lib/postcss-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const postcss = require('postcss');
const path = require('path');
const crypto = require('crypto');

const urlRegexp = new RegExp('url\\s*\\((\\s*"([^"]+)"|\'([^\']+)\'|([^\'")]+))\\)');
const urlRegexp = /url\s*\((\s*"([^"]+)"|'([^']+)'|([^'")]+))\)/;

/** @typedef {{resolved: string[], unresolved: string[], relative: string[]}} SvgPaths */

Expand Down Expand Up @@ -74,7 +74,7 @@ function getSvgPaths (postCssRoot, webpackResolve, context) {
})
))
.then((resolvedFilenames) => ({
// Original paths (unprocessed relative to the current css file context)
// Original paths (unprocessed relative to the current css file context)
unresolved: unresolvedPaths,
// Absolute paths
resolved: resolvedFilenames,
Expand Down Expand Up @@ -151,7 +151,7 @@ function replaceIconFontDeclarations (fontName, postCssRoot, svgPaths) {
*/
function addFontDeclaration (fontName, postCssRoot, enforcedSvgHeight, svgPaths) {
// The options are passed as a query string so we use the relative svg paths to reduce the path length per file
const options = { svgs: svgPaths.relative, name: fontName, enforcedSvgHeight: enforcedSvgHeight };
const options = { svgs: svgPaths.resolved, name: fontName, enforcedSvgHeight: enforcedSvgHeight };
Copy link
Owner

@jantimon jantimon Mar 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use only relative paths here.. otherwise webpack won't be able to share caches

// Resolve the icon font plugin directoy in case the iconfont-webpack-plugin is used as a sub dependency
const iconFontPluginDirectory = path.dirname(require.resolve('../'));
// Use paths always with slash also for win32 to prevent an issues with resolving the placeholder on windows
Expand All @@ -171,33 +171,42 @@ function addFontDeclaration (fontName, postCssRoot, enforcedSvgHeight, svgPaths)
/**
* PostCSS Plugin factory
*/
module.exports = postcss.plugin('iconfont-webpack', config => function (root, result) {
/* istanbul ignore if: Skip processing empty results */
if (!result || !result.opts || !result.opts.from) {
return;
}
const cssFilename = result.opts.from;
const context = path.dirname(cssFilename);
return getSvgPaths(root, config.resolve, context)
.then(/** @returns {any} */function (svgPaths) {
// Stop if the css file contains no `font-icon:url('..');` declarations
if (svgPaths.resolved.length === 0) {
// @ts-ignore
module.exports = (config) => {
return {
postcssPlugin: 'iconfont-webpack',
// @ts-ignore
Once (root, { result }) {
// TODO: To check if no result can be mocked at all
/* istanbul ignore if */
if (!result || !result.opts || !result.opts.from) {
return;
}
// Generate a font icon name
const md5sum = crypto.createHash('md5');
md5sum.update(JSON.stringify(svgPaths.relative));
let fontName = md5sum.digest('hex').substr(0, 6);
// Prefix the fontname with a letter as fonts with a leading number are not allowed
fontName = config.fontNamePrefix + String.fromCharCode(fontName.charCodeAt(0) + 20) + fontName.substr(1);
// Update the css
const processCssPromise = Promise.all([
// add the font faces
addFontDeclaration(fontName, root, config.enforcedSvgHeight, svgPaths),
// replace the `font-icon` occurences
replaceIconFontDeclarations(fontName, root, svgPaths)
]);
// Return an empty promise
return processCssPromise.then(function () { });
});
});

const cssFilename = result.opts.from;
const context = path.dirname(cssFilename);
return getSvgPaths(root, config.resolve, context)
.then(/** @returns {any} */function (svgPaths) {
// Stop if the css file contains no `font-icon:url('..');` declarations
if (svgPaths.resolved.length === 0) {
return;
}
// Generate a font icon name
const md5sum = crypto.createHash('md5');
md5sum.update(JSON.stringify(svgPaths.relative));
let fontName = md5sum.digest('hex').substring(0, 6);
// Prefix the fontname with a letter as fonts with a leading number are not allowed
fontName = config.fontNamePrefix + String.fromCharCode(fontName.charCodeAt(0) + 20) + fontName.substring(1);
// Update the css
const processCssPromise = Promise.all([
// add the font faces
addFontDeclaration(fontName, root, config.enforcedSvgHeight, svgPaths),
// replace the `font-icon` occurences
replaceIconFontDeclarations(fontName, root, svgPaths)
]);
// Return an empty promise
return processCssPromise.then(function () { });
});
}
};
};
35 changes: 17 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,28 @@
},
"homepage": "https://github.com/jantimon/iconfont-webpack-plugin",
"devDependencies": {
"@types/node": "13.9.8",
"ava": "0.25.0",
"commitizen": "4.2.3",
"conventional-changelog-cli": "2.1.1",
"css-loader": "4.2.1",
"@types/node": "17.0.5",
"ava": "3.15.0",
"commitizen": "4.2.4",
"conventional-changelog-cli": "2.2.2",
"css-loader": "5.2.7",
"cz-conventional-changelog": "3.3.0",
"mini-css-extract-plugin": "1.3.5",
"mini-css-extract-plugin": "2.4.0",
"npm-run-all": "4.1.5",
"nyc": "15.1.0",
"postcss-loader": "4.2.0",
"semistandard": "14.2.3",
"standard-version": "9.1.0",
"style-loader": "2.0.0",
"typescript": "3.8.3",
"webpack": "4.46.0",
"webpack-cli": "4.5.0"
"postcss": "8.4.5",
"postcss-loader": "6.2.1",
"semistandard": "16.0.1",
"standard-version": "9.3.2",
"style-loader": "3.3.1",
"typescript": "4.5.4",
"webpack": "5.65.0",
"webpack-cli": "4.9.1"
},
"dependencies": {
"loader-utils": "1.4.0",
"postcss": "7.0.35",
"svg2ttf": "5.0.0",
"svgicons2svgfont": "9.1.1",
"ttf2woff": "2.0.2"
"svg2ttf": "6.0.3",
"svgicons2svgfont": "10.0.5",
"ttf2woff": "3.0.0"
},
"peerDependencies": {
"webpack": ">=3",
Expand Down
10 changes: 5 additions & 5 deletions test/postcss-plugin.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';
/* eslint max-len: off, quotes:off, arrow-parens:off */
import test from 'ava';
import path from 'path';
import postcss from 'postcss';
import postcssPlugin from '../lib/postcss-plugin.js';
import { loader } from './helpers/loader-mock.js';
const test = require('ava');
const path = require('path');
const postcss = require('postcss');
const postcssPlugin = require('../lib/postcss-plugin.js');
const loader = require('./helpers/loader-mock.js').loader;

const iconFontPath = path.dirname(__dirname).replace(/\\/g, '/');

Expand Down