From dbe02e42e5bf05a04e74ccb51d576aa83b5fddff Mon Sep 17 00:00:00 2001 From: JW Date: Sun, 3 Sep 2023 17:03:39 +0800 Subject: [PATCH] :sparkles: support nodejs svgo --- .changeset/config.json | 2 +- .changeset/red-ways-relax.md | 5 ++ .../webpack/build/webpack.common.config.js | 6 ++ package.json | 3 +- pnpm-lock.yaml | 90 +++++++++++++++++-- src/exports/vite.ts | 5 +- src/exports/webpack.ts | 13 ++- src/index.ts | 36 +++++++- 8 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 .changeset/red-ways-relax.md diff --git a/.changeset/config.json b/.changeset/config.json index e42a790..2dbef0f 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,5 +6,5 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["vite-template", "webpack-template"] + "ignore": ["vite-template", "webpack-template", "vite-template"] } \ No newline at end of file diff --git a/.changeset/red-ways-relax.md b/.changeset/red-ways-relax.md new file mode 100644 index 0000000..5a9f63c --- /dev/null +++ b/.changeset/red-ways-relax.md @@ -0,0 +1,5 @@ +--- +"@svgr-rs/svgrs-plugin": patch +--- + +support nodejs svgo diff --git a/examples/webpack/build/webpack.common.config.js b/examples/webpack/build/webpack.common.config.js index ed21e14..1ecb0a7 100644 --- a/examples/webpack/build/webpack.common.config.js +++ b/examples/webpack/build/webpack.common.config.js @@ -51,6 +51,12 @@ const common = { }, { loader: '@svgr-rs/svgrs-plugin/webpack', + // options: { + // svgo: true, + // svgoConfig: { + // plugins: ['preset-default'], + // }, + // }, }, ], }, diff --git a/package.json b/package.json index 09e56f3..2251acc 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,8 @@ }, "dependencies": { "@rollup/pluginutils": "^5.0.2", - "@svgr-rs/core": "^0.0.12" + "@svgr-rs/core": "^0.0.12", + "svgo": "^3.0.2" }, "devDependencies": { "@aiou/eslint-config": "0.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93b691f..963fb4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,7 @@ importers: rollup-plugin-esbuild: ^5.0.0 rollup-plugin-filesize: 9.1.2 rollup-plugin-node-externals: 5.1.2 + svgo: ^3.0.2 ts-node: ^10.7.0 tslib: 2.4.0 ttypescript: 1.5.15 @@ -37,6 +38,7 @@ importers: dependencies: '@rollup/pluginutils': 5.0.2_rollup@3.19.1 '@svgr-rs/core': 0.0.12 + svgo: 3.0.2 devDependencies: '@aiou/eslint-config': 0.10.0_2ruvpbjjavfie6oibe5ebrxc24 '@changesets/cli': 2.21.1 @@ -3261,7 +3263,6 @@ packages: /@trysound/sax/0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - dev: true /@tsconfig/node10/1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} @@ -4858,7 +4859,6 @@ packages: /boolbase/1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true /boxen/2.1.0: resolution: {integrity: sha512-luq3RQOt2U5sUX+fiu+qnT+wWnHDcATLpEe63jvge6GUZO99AKbVRfp97d2jgLvq1iQa0ORzaAm4lGVG52ZSlw==} @@ -5530,7 +5530,6 @@ packages: /commander/7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} - dev: true /commander/8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} @@ -5871,6 +5870,16 @@ packages: nth-check: 2.1.1 dev: true + /css-select/5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + dev: false + /css-selector-tokenizer/0.8.0: resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==} dependencies: @@ -5886,10 +5895,25 @@ packages: source-map: 0.6.1 dev: true + /css-tree/2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.0.2 + dev: false + + /css-tree/2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + dev: false + /css-what/6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} - dev: true /css/2.2.4: resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==} @@ -6057,6 +6081,13 @@ packages: css-tree: 1.1.3 dev: true + /csso/5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + css-tree: 2.2.1 + dev: false + /cssom/0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} dev: true @@ -6479,9 +6510,16 @@ packages: entities: 2.2.0 dev: true + /dom-serializer/2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + dev: false + /domelementtype/2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true /domexception/2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} @@ -6497,6 +6535,13 @@ packages: domelementtype: 2.3.0 dev: true + /domhandler/5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: false + /domutils/2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} dependencies: @@ -6505,6 +6550,14 @@ packages: domhandler: 4.3.1 dev: true + /domutils/3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: false + /dot-case/3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: @@ -6625,6 +6678,11 @@ packages: engines: {node: '>=0.12'} dev: true + /entities/4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: false + /env-paths/2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -10875,6 +10933,14 @@ packages: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: true + /mdn-data/2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + dev: false + + /mdn-data/2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: false + /media-typer/0.3.0: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} @@ -11381,7 +11447,6 @@ packages: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: boolbase: 1.0.0 - dev: true /num2fraction/1.2.2: resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} @@ -15172,6 +15237,19 @@ packages: stable: 0.1.8 dev: true + /svgo/3.0.2: + resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + csso: 5.0.5 + picocolors: 1.0.0 + dev: false + /swr/1.3.0_react@18.0.0: resolution: {integrity: sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==} peerDependencies: diff --git a/src/exports/vite.ts b/src/exports/vite.ts index d4e3c77..bdc7712 100644 --- a/src/exports/vite.ts +++ b/src/exports/vite.ts @@ -4,6 +4,8 @@ import { createFilter } from '@rollup/pluginutils' import { transform } from '@svgr-rs/core' import { transformWithEsbuild } from 'vite' +import { svgo } from '../index' + import type { Config, State } from '@svgr-rs/core' import type { ESBuildOptions, Plugin } from 'vite' @@ -47,7 +49,7 @@ export const svgrs = ({ }, async transform(code, id) { if (filter(cleanUrl(id))) { - const raw = await fs.readFile(cleanUrl(id), 'utf-8') + let raw = await fs.readFile(cleanUrl(id), 'utf-8') const state: State = { componentName: namedExport, filePath: id, @@ -59,6 +61,7 @@ export const svgrs = ({ name: 'svgrs-plugin/vite', } } + raw = await svgo(raw, config, state) const svgrsCode = await transform( raw, { namedExport, exportType, jsxRuntime, icon, ...config }, diff --git a/src/exports/webpack.ts b/src/exports/webpack.ts index 461e3ba..bbde1ec 100644 --- a/src/exports/webpack.ts +++ b/src/exports/webpack.ts @@ -8,9 +8,14 @@ import path from 'node:path' import { transform } from '@svgr-rs/core' +import { svgo } from '../index' + import type { Config, State } from '@svgr-rs/core' import type { LoaderContext } from 'webpack' +/** + * NOTE: @svgr-rs/svgo not production ready yet. Use svgo instead. + */ async function svgrsLoader(this: LoaderContext, source: string) { this.cacheable && this.cacheable() const callback = this.async() @@ -38,7 +43,7 @@ async function svgrsLoader(this: LoaderContext, source: string) { // NOTE: state.caller will force make svgrs use 'named' export type state.caller = { previousExport, - name: 'svgrs-plugin/vite', + name: 'svgrs-plugin/webpack', } } const options: Config = { @@ -49,11 +54,13 @@ async function svgrsLoader(this: LoaderContext, source: string) { ...config, } if (!previousExport) { - const code = await transform(source, options, state) + let code = await svgo(source, config, state) + code = await transform(code, options, state) callback(null, code) } else { const content = await fs.readFile(this.resourcePath, 'utf-8') - const code = await transform(content, options, state) + let code = await svgo(content, config, state) + code = await transform(code, options, state) callback(null, code) } } diff --git a/src/index.ts b/src/index.ts index 82cf37d..39f8181 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,35 @@ -// polyfill for rollup-plugin-condition-exports +/** + * Based on @svgr/plugin-svgo + * Copyright 2017 Smooth Code + */ + +import type { Config, State } from '@svgr-rs/core' + +/** + * @todo Load svgo config from config file + */ +export const getSvgoConfig = (config: Config): any => { + // @ts-expect-error -- ignore + if (config.svgoConfig) { + // @ts-expect-error -- ignore + return config.svgoConfig + } + return {} +} + +export const svgo = async (code: string, config: Config, state: State) => { + if (!config.svgo) { + return code + } + const { optimize } = await import('svgo') + const svgoConfig = getSvgoConfig(config) + const result = optimize(code, { ...svgoConfig, path: state.filePath }) + + // @ts-expect-error -- ignore + if (result.modernError) { + // @ts-expect-error -- ignore + throw result.modernError + } + + return result.data +}