diff --git a/.changeset/tall-elephants-cross.md b/.changeset/tall-elephants-cross.md new file mode 100644 index 000000000000..43c7a45eb76c --- /dev/null +++ b/.changeset/tall-elephants-cross.md @@ -0,0 +1,7 @@ +--- +'@modern-js/module-tools': patch +--- + +fix(module-tools): should not remove SVG viewBox attribute + +fix(module-tools): 避免移除 SVG viewBox 属性 diff --git a/packages/solutions/module-tools/src/builder/feature/asset.ts b/packages/solutions/module-tools/src/builder/feature/asset.ts index acb807d46308..771db7701902 100644 --- a/packages/solutions/module-tools/src/builder/feature/asset.ts +++ b/packages/solutions/module-tools/src/builder/feature/asset.ts @@ -1,11 +1,12 @@ import { basename, join, extname, relative, dirname, resolve } from 'path'; import fs from 'fs'; +import _ from '@modern-js/utils/lodash'; import type { Loader } from 'esbuild'; import { createFilter } from '@rollup/pluginutils'; import { transform } from '../../../compiled/@svgr/core'; import svgo from '../../../compiled/@svgr/plugin-svgo'; import jsx from '../../../compiled/@svgr/plugin-jsx'; -import { ICompiler } from '../../types'; +import type { ICompiler, SvgrOptions } from '../../types'; import { assetExt } from '../../constants/file'; import { normalizeSlashes, getHash } from '../../utils'; @@ -58,6 +59,25 @@ function encodeSVG(buffer: Buffer) { ); } +const getDefaultSVGRConfig = (): SvgrOptions => ({ + svgo: true, + svgoConfig: { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + // viewBox is required to resize SVGs with CSS. + // @see https://github.com/svg/svgo/issues/1128 + removeViewBox: false, + }, + }, + }, + 'prefixIds', + ], + }, +}); + /** * * @param this Compiler @@ -92,7 +112,10 @@ export async function getAssetContents( let contents: string | Buffer = normalizedPublicPath; let loader: Loader = 'text'; - const config = typeof svgr === 'boolean' ? {} : svgr; + const defaultConfig = getDefaultSVGRConfig(); + const config = + typeof svgr === 'boolean' ? defaultConfig : _.merge(defaultConfig, svgr); + const filter = createFilter(config.include || SVG_REGEXP, config.exclude); if (svgr && filter(assetPath)) { // svgr jsx-loader diff --git a/tests/integration/module/fixtures/build/asset/asset.test.ts b/tests/integration/module/fixtures/build/asset/asset.test.ts index 3a7f8b091c0f..0cdd5594f51e 100644 --- a/tests/integration/module/fixtures/build/asset/asset.test.ts +++ b/tests/integration/module/fixtures/build/asset/asset.test.ts @@ -54,6 +54,8 @@ describe('asset.svgr', () => { const distFilePath = path.join(fixtureDir, './dist/bundle/index.js'); const content = await fs.readFile(distFilePath, 'utf-8'); expect(content.includes(`jsx("svg"`)).toBeTruthy(); + // should not remove SVG viewBox attribute + expect(content.includes('viewBox: "0 0 841.9 595.3"')).toBeTruthy(); }); it('bundleless', async () => { const configFile = 'bundleless.config.ts';