From b96c46da65d559cd4a46a79f72dcdc80df8f20d8 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Sun, 21 Aug 2022 16:13:02 -0400 Subject: [PATCH] Fixes icon font generation in both cli/webpack - Adds custom fantasticon webpack plugin --- .fantasticonrc.js | 11 ------ package.json | 2 +- webpack.config.js | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- yarn.lock | 20 +++++----- 4 files changed, 116 insertions(+), 26 deletions(-) diff --git a/.fantasticonrc.js b/.fantasticonrc.js index 03417d1..2c74be9 100644 --- a/.fantasticonrc.js +++ b/.fantasticonrc.js @@ -27,17 +27,6 @@ const config = { html: './icons-contribution.json', json: './images/icons/template/mapping.json', }, - onComplete: _fontConfig => { - const fs = require('fs'); - // Update the icons contribution point in package.json - const package = require('./package.json'); - package.contributes.icons = require('./icons-contribution.json').icons; - - const packageJSON = `${JSON.stringify(package, undefined, '\t')}\n`; - - fs.writeFileSync('./package.json', packageJSON); - fs.rmSync('./icons-contribution.json'); - }, }; module.exports = config; diff --git a/package.json b/package.json index 3374fd3..03cd1ce 100644 --- a/package.json +++ b/package.json @@ -11606,7 +11606,6 @@ "eslint-plugin-import": "2.26.0", "eslint-plugin-lit": "1.6.1", "fantasticon": "1.2.3", - "fantasticon-webpack-plugin": "0.0.4", "fork-ts-checker-webpack-plugin": "6.5.2", "glob": "8.0.3", "html-loader": "4.1.0", @@ -11619,6 +11618,7 @@ "prettier": "2.7.1", "sass": "1.54.5", "sass-loader": "13.0.2", + "schema-utils": "4.0.0", "svgo": "2.8.0", "terser-webpack-plugin": "5.3.5", "ts-loader": "9.3.1", diff --git a/webpack.config.js b/webpack.config.js index e8e0d69..9d1e2e8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,20 +1,21 @@ //@ts-check /** @typedef {import('webpack').Configuration} WebpackConfig **/ -const fs = require('fs'); const { spawnSync } = require('child_process'); -const path = require('path'); const CircularDependencyPlugin = require('circular-dependency-plugin'); const { CleanWebpackPlugin: CleanPlugin } = require('clean-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const CspHtmlPlugin = require('csp-html-webpack-plugin'); const esbuild = require('esbuild'); -const FantasticonPlugin = require('fantasticon-webpack-plugin'); +const { generateFonts } = require('fantasticon'); const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin'); +const fs = require('fs'); const HtmlPlugin = require('html-webpack-plugin'); const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); const JSON5 = require('json5'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const path = require('path'); +const { validate } = require('schema-utils'); const TerserPlugin = require('terser-webpack-plugin'); const { WebpackError, webpack, optimize } = require('webpack'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; @@ -91,8 +92,19 @@ function getExtensionConfig(target, mode, env) { plugins.push( new FantasticonPlugin({ - runOnComplete: true, configPath: '.fantasticonrc.js', + onBefore: () => + spawnSync('yarn', ['run', 'icons:svgo'], { + cwd: __dirname, + encoding: 'utf8', + shell: true, + }), + onComplete: () => + spawnSync('yarn', ['run', 'icons:apply'], { + cwd: __dirname, + encoding: 'utf8', + shell: true, + }), }), ); } @@ -628,3 +640,92 @@ function resolveTSConfig(configFile) { const json = JSON5.parse(data.substring(start, end)); return json; } + +const schema = { + type: 'object', + properties: { + config: { + type: 'object', + }, + configPath: { + type: 'string', + }, + onBefore: { + instanceof: 'Function', + }, + onComplete: { + instanceof: 'Function', + }, + }, +}; + +class FantasticonPlugin { + alreadyRun = false; + + constructor(options = {}) { + this.pluginName = 'fantasticon'; + this.options = options; + + validate( + // @ts-ignore + schema, + options, + { + name: this.pluginName, + baseDataPath: 'options', + }, + ); + } + + /** + * @param {import("webpack").Compiler} compiler + */ + apply(compiler) { + const { + config = undefined, + configPath = undefined, + onBefore = undefined, + onComplete = undefined, + } = this.options; + + let loadedConfig; + if (configPath) { + try { + loadedConfig = require(path.join(__dirname, configPath)); + } catch (ex) { + console.error(`[${this.pluginName}] Error loading configuration: ${ex}`); + } + } + + if (!loadedConfig && !config) { + console.error(`[${this.pluginName}] Error loading configuration: no configuration found`); + return; + } + + const fontConfig = { ...(loadedConfig ?? {}), ...(config ?? {}) }; + + // TODO@eamodio: Figure out how to add watching for the fontConfig.inputDir + // Maybe something like: https://github.com/Fridus/webpack-watch-files-plugin + + /** + * @this {FantasticonPlugin} + * @param {import("webpack").Compiler} compiler + */ + async function generate(compiler) { + if (compiler.watchMode) { + if (this.alreadyRun) return; + this.alreadyRun = true; + } + + const logger = compiler.getInfrastructureLogger(this.pluginName); + logger.log(`Generating icon font...`); + await onBefore?.(fontConfig); + await generateFonts(fontConfig); + await onComplete?.(fontConfig); + logger.log(`Generated icon font`); + } + + compiler.hooks.beforeRun.tapPromise(this.pluginName, generate.bind(this)); + compiler.hooks.watchRun.tapPromise(this.pluginName, generate.bind(this)); + } +} diff --git a/yarn.lock b/yarn.lock index 290926e..5355c7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6099,16 +6099,7 @@ schema-utils@2.7.0: ajv "^6.12.2" ajv-keywords "^3.4.1" -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: +schema-utils@4.0.0, schema-utils@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== @@ -6118,6 +6109,15 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + seek-bzip@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4"