From 97690abc9422307f9ca52267391d4f8d62752e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Mon, 6 Jan 2025 17:54:43 +0100 Subject: [PATCH] fix(core): restore core svg file-loader (#10820) --- packages/docusaurus-plugin-svgr/src/index.ts | 8 ++--- .../docusaurus-plugin-svgr/src/svgrLoader.ts | 36 ++++++++++++++----- packages/docusaurus-types/src/plugin.d.ts | 2 +- packages/docusaurus-utils/src/webpackUtils.ts | 10 ++++++ packages/docusaurus/src/webpack/base.ts | 1 + project-words.txt | 1 + website/_dogfooding/dogfooding.css | 9 +++++ website/_dogfooding/red.svg | 4 +++ 8 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 website/_dogfooding/red.svg diff --git a/packages/docusaurus-plugin-svgr/src/index.ts b/packages/docusaurus-plugin-svgr/src/index.ts index ab92a1ee1507..32a9c17b7435 100644 --- a/packages/docusaurus-plugin-svgr/src/index.ts +++ b/packages/docusaurus-plugin-svgr/src/index.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {createLoader} from './svgrLoader'; +import {enhanceConfig} from './svgrLoader'; import type {LoadContext, Plugin} from '@docusaurus/types'; import type {PluginOptions, Options} from './options'; @@ -16,11 +16,7 @@ export default function pluginSVGR( return { name: 'docusaurus-plugin-svgr', configureWebpack: (config, isServer) => { - return { - module: { - rules: [createLoader({isServer, svgrConfig: options.svgrConfig})], - }, - }; + enhanceConfig(config, {isServer, svgrConfig: options.svgrConfig}); }, }; } diff --git a/packages/docusaurus-plugin-svgr/src/svgrLoader.ts b/packages/docusaurus-plugin-svgr/src/svgrLoader.ts index 3744b9decca1..4520891385bd 100644 --- a/packages/docusaurus-plugin-svgr/src/svgrLoader.ts +++ b/packages/docusaurus-plugin-svgr/src/svgrLoader.ts @@ -8,7 +8,7 @@ import {getFileLoaderUtils} from '@docusaurus/utils'; import type {SVGRConfig, SVGOConfig} from './options'; -import type {RuleSetRule} from 'webpack'; +import type {Configuration, RuleSetRule} from 'webpack'; // TODO Docusaurus v4: change these defaults? // see https://github.com/facebook/docusaurus/issues/8297 @@ -37,7 +37,7 @@ const DefaultSVGRConfig: SVGRConfig = { type Params = {isServer: boolean; svgrConfig: SVGRConfig}; -function createSVGRLoader(params: Params): RuleSetRule { +function createSVGRRule(params: Params): RuleSetRule { const options: SVGRConfig = { ...DefaultSVGRConfig, ...params.svgrConfig, @@ -48,22 +48,42 @@ function createSVGRLoader(params: Params): RuleSetRule { }; } -export function createLoader(params: Params): RuleSetRule { +export function enhanceConfig(config: Configuration, params: Params): void { const utils = getFileLoaderUtils(params.isServer); - return { + + const rules = config?.module?.rules as RuleSetRule[]; + + const existingSvgRule: RuleSetRule = (() => { + const rule = rules.find( + (r) => String(r.test) === String(utils.rules.svgs().test), + ); + if (!rule) { + throw new Error( + "Docusaurus built-in SVG rule couldn't be found. The SVGR plugin can't enhance it.", + ); + } + return rule; + })(); + + const newSvgRule: RuleSetRule = { test: /\.svg$/i, oneOf: [ { - use: [createSVGRLoader(params)], + use: [createSVGRRule(params)], // We don't want to use SVGR loader for non-React source code // ie we don't want to use SVGR for CSS files... issuer: { and: [/\.(?:tsx?|jsx?|mdx?)$/i], }, }, - { - use: [utils.loaders.url({folder: 'images'})], - }, + existingSvgRule, ], }; + + // This is annoying, but we have to "wrap" the existing SVG rule + // Adding another extra SVG rule (first or last) will not "override" + // the default: both rules will be applied (from last to bottom) leading to + // conflicting behavior. + const index = rules.indexOf(existingSvgRule); + rules[index] = newSvgRule; } diff --git a/packages/docusaurus-types/src/plugin.d.ts b/packages/docusaurus-types/src/plugin.d.ts index 51cecbf64783..0e428e2bbdee 100644 --- a/packages/docusaurus-types/src/plugin.d.ts +++ b/packages/docusaurus-types/src/plugin.d.ts @@ -140,7 +140,7 @@ export type Plugin = { isServer: boolean, configureWebpackUtils: ConfigureWebpackUtils, content: Content, - ) => ConfigureWebpackResult; + ) => ConfigureWebpackResult | void; configurePostCss?: (options: PostCssOptions) => PostCssOptions; getThemePath?: () => string; getTypeScriptThemePath?: () => string; diff --git a/packages/docusaurus-utils/src/webpackUtils.ts b/packages/docusaurus-utils/src/webpackUtils.ts index dc3dd2b1181a..5ccca490841f 100644 --- a/packages/docusaurus-utils/src/webpackUtils.ts +++ b/packages/docusaurus-utils/src/webpackUtils.ts @@ -43,6 +43,7 @@ type FileLoaderUtils = { }; rules: { images: () => RuleSetRule; + svgs: () => RuleSetRule; fonts: () => RuleSetRule; media: () => RuleSetRule; otherAssets: () => RuleSetRule; @@ -119,6 +120,15 @@ function createFileLoaderUtils({ test: /\.(?:ico|jpe?g|png|gif|webp|avif)(?:\?.*)?$/i, }), + /** + * The SVG rule is isolated on purpose: our SVGR plugin enhances it + * See https://github.com/facebook/docusaurus/pull/10820 + */ + svgs: () => ({ + use: [loaders.url({folder: 'images'})], + test: /\.svg$/i, + }), + fonts: () => ({ use: [loaders.url({folder: 'fonts'})], test: /\.(?:woff2?|eot|ttf|otf)$/i, diff --git a/packages/docusaurus/src/webpack/base.ts b/packages/docusaurus/src/webpack/base.ts index 9f6c2ae08572..6a77aa0f03f7 100644 --- a/packages/docusaurus/src/webpack/base.ts +++ b/packages/docusaurus/src/webpack/base.ts @@ -251,6 +251,7 @@ export async function createBaseConfig({ module: { rules: [ fileLoaderUtils.rules.images(), + fileLoaderUtils.rules.svgs(), fileLoaderUtils.rules.fonts(), fileLoaderUtils.rules.media(), fileLoaderUtils.rules.otherAssets(), diff --git a/project-words.txt b/project-words.txt index d9de4b886273..5a0ef4e6752d 100644 --- a/project-words.txt +++ b/project-words.txt @@ -323,6 +323,7 @@ Sucipto sunsetting supabase Supabase +svgs swizzlable Tagkey Teik diff --git a/website/_dogfooding/dogfooding.css b/website/_dogfooding/dogfooding.css index cd621d24d4ad..48983473fe16 100644 --- a/website/_dogfooding/dogfooding.css +++ b/website/_dogfooding/dogfooding.css @@ -10,6 +10,15 @@ html { &.plugin-docs.plugin-id-docs-tests { .red > a { color: red; + + &::after { + background-image: url('./red.svg'); + background-size: contain; + margin-left: 0.5rem; + width: 1rem; + height: 1rem; + content: ' '; + } } .navbar { diff --git a/website/_dogfooding/red.svg b/website/_dogfooding/red.svg new file mode 100644 index 000000000000..dba2f0d09c3e --- /dev/null +++ b/website/_dogfooding/red.svg @@ -0,0 +1,4 @@ + + + +