Skip to content

Commit 0f6d311

Browse files
worldwenworldzhao
authored andcommitted
ifeat(svg-icon): use @vue/compiler-sfc instead of vue-loader to support vue2/3 & bug fix
1 parent 7aa31fd commit 0f6d311

18 files changed

+364
-94
lines changed

.changeset/itchy-starfishes-dress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'v-icon-svg': minor
3+
---
4+
5+
use @vue/compiler-sfc instead of vue-loader to support vue2/3 & bug fix

README.md

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# v-icon-svg
22

3-
> Renders SVG icon strings in Vue, supporting size and color adjustments via CSS `font-size` and `color` properties.
3+
> Renders SVG icon strings, supporting size and color adjustments via CSS `font-size` and `color` properties.
44
55
- [Demo](https://worldzhao.github.io/v-icon-svg/index.html)
66

@@ -29,10 +29,10 @@ import { SVGIcon } from 'v-icon-svg/vue2';
2929

3030
This package offers two ways of usage:
3131

32-
| Solution | Features | Applicable Scenarios |
33-
| -------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
34-
| **🚀 Runtime Solution** | Pass SVG string directly, processed at runtime | Dynamic icons, third-party SVGs, high flexibility needs |
35-
| **⚡ Build-time Solution** | Webpack/Rspack plugin, processed at build time | Static icon resources, high performance needs, development experience priority, **currently Vue2 with vue-loader only** |
32+
| Solution | Features | Applicable Scenarios |
33+
| -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------ |
34+
| **🚀 Runtime Solution** | Pass SVG string directly, processed at runtime | Dynamic icons, third-party SVGs, high flexibility needs |
35+
| **⚡ Build-time Solution** | Webpack/Rspack plugin, processed at build time | Static icon resources, high performance needs, development experience priority |
3636

3737
---
3838

@@ -169,8 +169,7 @@ The runtime solution supports two rendering modes:
169169

170170
Provides a Webpack/Rspack(Rsbuild) plugin that allows direct import of SVG files as Vue components, eliminating the need to manually handle SVG content.
171171

172-
> Note: Depends on vue-loader's resource handling capabilities. Ensure vue-loader is correctly configured.
173-
> [unplugin-vue](https://github.com/unplugin/unplugin-vue) is not yet supported.
172+
> @vue/compiler-sfc counterpart of the vue version is required.
174173
175174
### Configure in webpack.config.js
176175

@@ -183,20 +182,33 @@ module.exports = {
183182
// ... other plugins
184183
new SvgIconPlugin({
185184
include: /src\/assets\/icons/, // Only process SVGs in this specific directory
185+
rawQuery: 'raw',
186+
urlQuery: 'url',
187+
inlineQuery: 'inline',
186188
}),
187189
],
188190
};
189191
```
190192

193+
```js
194+
import ArrowIcon from './arrow.svg'; // Vue Component
195+
import arrowSvg from './arrow.svg?raw'; // Original string
196+
import arrowUrl from './arrow.svg?url'; // File URL
197+
import arrowInline from './arrow.svg?inline'; // Base64 inline
198+
```
199+
191200
> Note: After configuring `include`, other SVG rule configurations will ignore resources matched by this plugin's `include`.
192201
193202
### Configuration Options
194203

195-
| Option | Type | Default | Description |
196-
| ------- | ------ | -------- | ---------------------------------- |
197-
| test | RegExp | /\.svg$/ | Matches files to be processed. |
198-
| include | RegExp | null | Only include matching directories. |
199-
| exclude | RegExp | null | Exclude matching directories. |
204+
| Option | Type | Default | Description |
205+
| ----------- | ------ | -------- | --------------------------------------------------------------- |
206+
| test | RegExp | /\.svg$/ | Matches files to be processed. |
207+
| include | RegExp | null | Only include matching directories. |
208+
| exclude | RegExp | null | Exclude matching directories. |
209+
| rawQuery | String | 'raw' | Return original SVG string with this query parameter |
210+
| urlQuery | String | 'url' | Returns the SVG file URL with this query parameter. |
211+
| inlineQuery | String | 'inline' | Returns base64-encoded inline content with this query parameter |
200212

201213
### Usage in Vue Components
202214

@@ -272,7 +284,7 @@ module.exports = {
272284
## 🛠️ Compatibility
273285

274286
- **Vue**: 2.7+ / 3.0+
275-
- **Build Tools**: Webpack / Rspack 1+ with Vue2 with vue-loader only
287+
- **Build Tools**: Webpack 5 / Rspack 1
276288
- **Browsers**: Modern browsers (supporting SVG `<symbol>` and `<use>` elements)
277289

278290
---

README.zh-CN.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ import { SVGIcon } from 'v-icon-svg/vue2';
2727

2828
本包提供两种使用方式:
2929

30-
| 方案 | 特点 | 适用场景 |
31-
| ----------------- | ------------------------------- | --------------------------------------------------------------------------- |
32-
| **🚀 运行时方案** | 直接传入 SVG 字符串,运行时处理 | 动态图标、第三方 SVG、灵活性要求高 |
33-
| **⚡ 构建时方案** | Webpack/Rspack 插件,构建时处理 | 静态图标资源、性能要求高、开发体验优先**暂时仅支持 Vue2 with vue-loader** |
30+
| 方案 | 特点 | 适用场景 |
31+
| ----------------- | ------------------------------- | -------------------------------------- |
32+
| **🚀 运行时方案** | 直接传入 SVG 字符串,运行时处理 | 动态图标、第三方 SVG、灵活性要求高 |
33+
| **⚡ 构建时方案** | Webpack/Rspack 插件,构建时处理 | 静态图标资源、性能要求高、开发体验优先 |
3434

3535
---
3636

@@ -168,8 +168,7 @@ import { SVGIcon } from 'v-icon-svg/vue2';
168168

169169
提供了一个 Webpack/Rspack(Rsbuild) 插件,可以直接将 SVG 文件作为 Vue 组件导入使用,无需手动处理 SVG 内容。
170170

171-
> 注意:依赖 vue-loader 的资源处理能力,请确保 vue-loader 已正确配置
172-
> [unplugin-vue](https://github.com/unplugin/unplugin-vue) 暂未支持
171+
> 需要安装 vue 版本对应的 @vue/compiler-sfc 对应版本
173172
174173
### 在 webpack.config.js 中配置
175174

@@ -182,20 +181,33 @@ module.exports = {
182181
// ... 其他插件
183182
new SvgIconPlugin({
184183
include: /src\/assets\/icons/, // 只处理特定目录的SVG
184+
rawQuery: 'raw',
185+
urlQuery: 'url',
186+
inlineQuery: 'inline',
185187
}),
186188
],
187189
};
188190
```
189191

192+
```js
193+
import ArrowIcon from './arrow.svg'; // Vue 组件
194+
import arrowSvg from './arrow.svg?raw'; // 原始字符串
195+
import arrowUrl from './arrow.svg?url'; // 文件 URL
196+
import arrowInline from './arrow.svg?inline'; // Base64 内联
197+
```
198+
190199
> 注意: 配置 include 后,其他 svg rule 规则将忽略该插件所配置的 include 的资源。
191200
192201
### 配置选项
193202

194-
| 选项 | 类型 | 默认值 | 说明 |
195-
| ------- | ------ | --------- | ---------------- |
196-
| test | RegExp | /\\.svg$/ | 匹配要处理的文件 |
197-
| include | RegExp | null | 仅包含匹配的目录 |
198-
| exclude | RegExp | null | 排除匹配的目录 |
203+
| 选项 | 类型 | 默认值 | 说明 |
204+
| ----------- | ------ | --------- | ----------------------------------------------------- |
205+
| test | RegExp | /\\.svg$/ | 匹配要处理的文件 |
206+
| include | RegExp | null | 仅包含匹配的目录 |
207+
| exclude | RegExp | null | 排除匹配的目录 |
208+
| rawQuery | String | 'raw' | 当资源包含此 query 参数时,返回原始 SVG 字符串 |
209+
| urlQuery | String | 'url' | 当资源包含此 query 参数时,返回 SVG 文件 URL |
210+
| inlineQuery | String | 'inline' | 当资源包含此 query 参数时,返回 base64 编码的内联内容 |
199211

200212
### 在 Vue 组件中使用
201213

@@ -271,7 +283,7 @@ module.exports = {
271283
## 🛠️ 兼容性
272284

273285
- **Vue**: 2.7+ / 3.0+
274-
- **构建工具**: Webpack / Rspack 1+ with Vue2 with vue-loader only
286+
- **构建工具**: Webpack 5/ Rspack 1
275287
- **浏览器**: 现代浏览器(支持 SVG `<symbol>``<use>` 元素)
276288

277289
---

examples/vue2.7/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"devDependencies": {
1717
"@rsbuild/core": "^1.3.15",
1818
"@rsbuild/plugin-vue2": "^1.0.3",
19+
"@vue/compiler-sfc": "^2.7.16",
1920
"tailwindcss": "^3"
2021
}
2122
}

examples/vue2.7/rsbuild.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { pluginVue2 } from '@rsbuild/plugin-vue2';
33
import path from 'path';
44
import { VueSvgIconPlugin } from 'v-icon-svg/plugin';
55

6+
process.env.DEBUG_VUE2 = 'true';
7+
68
export default defineConfig({
79
plugins: [pluginVue2()],
810
source: {

examples/vue3/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"devDependencies": {
1717
"@rsbuild/core": "^1.3.15",
1818
"@rsbuild/plugin-vue": "^1.0.7",
19+
"@vue/compiler-sfc": "^3.5.14",
1920
"tailwindcss": "^3",
2021
"typescript": "^5.7.3"
2122
}

examples/vue3/rsbuild.config.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import { defineConfig } from '@rsbuild/core';
22
import { pluginVue } from '@rsbuild/plugin-vue';
3+
import { VueSvgIconPlugin } from 'v-icon-svg/plugin';
34

45
export default defineConfig({
56
plugins: [pluginVue()],
6-
output:{ assetPrefix:"/v-icon-svg"},
7-
html: {
8-
title: 'v-icon-svg'
9-
}
7+
output: { assetPrefix: '/v-icon-svg' },
8+
html: {
9+
title: 'v-icon-svg',
10+
},
11+
tools: {
12+
rspack: (_config, { appendPlugins }) => {
13+
appendPlugins(
14+
new VueSvgIconPlugin({
15+
include: /src\/icons/,
16+
})
17+
);
18+
},
19+
},
1020
});

examples/vue3/src/App.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@
237237
</div>
238238
</div>
239239
</div>
240+
<h2 class="tw-text-2xl tw-font-bold tw-mb-6">构建插件模式</h2>
241+
<div class="tw-flex tw-gap-4">
242+
<IconMark class="tw-text-[34px] tw-text-blue-500 hover:tw-text-red-500" />
243+
<IconShare
244+
class="tw-text-[34px] tw-text-blue-500 hover:tw-text-red-500"
245+
/>
246+
</div>
240247
</div>
241248
</template>
242249

@@ -250,6 +257,8 @@ export default {
250257
import { ref } from 'vue';
251258
252259
import { SVGIcon } from 'v-icon-svg';
260+
import IconMark from './icons/mark.svg';
261+
import IconShare from './icons/share.svg';
253262
254263
const mySvgIconString =
255264
'<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#6b9bd2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>';

packages/v-icon-svg/README.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ import { SVGIcon } from 'v-icon-svg/vue2';
2929

3030
This package offers two ways of usage:
3131

32-
| Solution | Features | Applicable Scenarios |
33-
| -------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
34-
| **🚀 Runtime Solution** | Pass SVG string directly, processed at runtime | Dynamic icons, third-party SVGs, high flexibility needs |
35-
| **⚡ Build-time Solution** | Webpack/Rspack plugin, processed at build time | Static icon resources, high performance needs, development experience priority, **currently Vue2 with vue-loader only** |
32+
| Solution | Features | Applicable Scenarios |
33+
| -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------ |
34+
| **🚀 Runtime Solution** | Pass SVG string directly, processed at runtime | Dynamic icons, third-party SVGs, high flexibility needs |
35+
| **⚡ Build-time Solution** | Webpack/Rspack plugin, processed at build time | Static icon resources, high performance needs, development experience priority |
3636

3737
---
3838

@@ -169,8 +169,7 @@ The runtime solution supports two rendering modes:
169169

170170
Provides a Webpack/Rspack(Rsbuild) plugin that allows direct import of SVG files as Vue components, eliminating the need to manually handle SVG content.
171171

172-
> Note: Depends on vue-loader's resource handling capabilities. Ensure vue-loader is correctly configured.
173-
> [unplugin-vue](https://github.com/unplugin/unplugin-vue) is not yet supported.
172+
> @vue/compiler-sfc counterpart of the vue version is required.
174173
175174
### Configure in webpack.config.js
176175

@@ -183,20 +182,33 @@ module.exports = {
183182
// ... other plugins
184183
new SvgIconPlugin({
185184
include: /src\/assets\/icons/, // Only process SVGs in this specific directory
185+
rawQuery: 'raw',
186+
urlQuery: 'url',
187+
inlineQuery: 'inline',
186188
}),
187189
],
188190
};
189191
```
190192

193+
```js
194+
import ArrowIcon from './arrow.svg'; // Vue Component
195+
import arrowSvg from './arrow.svg?raw'; // Original string
196+
import arrowUrl from './arrow.svg?url'; // File URL
197+
import arrowInline from './arrow.svg?inline'; // Base64 inline
198+
```
199+
191200
> Note: After configuring `include`, other SVG rule configurations will ignore resources matched by this plugin's `include`.
192201
193202
### Configuration Options
194203

195-
| Option | Type | Default | Description |
196-
| ------- | ------ | -------- | ---------------------------------- |
197-
| test | RegExp | /\.svg$/ | Matches files to be processed. |
198-
| include | RegExp | null | Only include matching directories. |
199-
| exclude | RegExp | null | Exclude matching directories. |
204+
| Option | Type | Default | Description |
205+
| ----------- | ------ | -------- | --------------------------------------------------------------- |
206+
| test | RegExp | /\.svg$/ | Matches files to be processed. |
207+
| include | RegExp | null | Only include matching directories. |
208+
| exclude | RegExp | null | Exclude matching directories. |
209+
| rawQuery | String | 'raw' | Return original SVG string with this query parameter |
210+
| urlQuery | String | 'url' | Returns the SVG file URL with this query parameter. |
211+
| inlineQuery | String | 'inline' | Returns base64-encoded inline content with this query parameter |
200212

201213
### Usage in Vue Components
202214

@@ -272,7 +284,7 @@ module.exports = {
272284
## 🛠️ Compatibility
273285

274286
- **Vue**: 2.7+ / 3.0+
275-
- **Build Tools**: Webpack / Rspack 1+ with Vue2 with vue-loader only
287+
- **Build Tools**: Webpack 5 / Rspack 1
276288
- **Browsers**: Modern browsers (supporting SVG `<symbol>` and `<use>` elements)
277289

278290
---

packages/v-icon-svg/README.zh-CN.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ import { SVGIcon } from 'v-icon-svg/vue2';
2727

2828
本包提供两种使用方式:
2929

30-
| 方案 | 特点 | 适用场景 |
31-
| ----------------- | ------------------------------- | --------------------------------------------------------------------------- |
32-
| **🚀 运行时方案** | 直接传入 SVG 字符串,运行时处理 | 动态图标、第三方 SVG、灵活性要求高 |
33-
| **⚡ 构建时方案** | Webpack/Rspack 插件,构建时处理 | 静态图标资源、性能要求高、开发体验优先**暂时仅支持 Vue2 with vue-loader** |
30+
| 方案 | 特点 | 适用场景 |
31+
| ----------------- | ------------------------------- | -------------------------------------- |
32+
| **🚀 运行时方案** | 直接传入 SVG 字符串,运行时处理 | 动态图标、第三方 SVG、灵活性要求高 |
33+
| **⚡ 构建时方案** | Webpack/Rspack 插件,构建时处理 | 静态图标资源、性能要求高、开发体验优先 |
3434

3535
---
3636

@@ -168,8 +168,7 @@ import { SVGIcon } from 'v-icon-svg/vue2';
168168

169169
提供了一个 Webpack/Rspack(Rsbuild) 插件,可以直接将 SVG 文件作为 Vue 组件导入使用,无需手动处理 SVG 内容。
170170

171-
> 注意:依赖 vue-loader 的资源处理能力,请确保 vue-loader 已正确配置
172-
> [unplugin-vue](https://github.com/unplugin/unplugin-vue) 暂未支持
171+
> 需要安装 vue 版本对应的 @vue/compiler-sfc 对应版本
173172
174173
### 在 webpack.config.js 中配置
175174

@@ -182,20 +181,33 @@ module.exports = {
182181
// ... 其他插件
183182
new SvgIconPlugin({
184183
include: /src\/assets\/icons/, // 只处理特定目录的SVG
184+
rawQuery: 'raw',
185+
urlQuery: 'url',
186+
inlineQuery: 'inline',
185187
}),
186188
],
187189
};
188190
```
189191

192+
```js
193+
import ArrowIcon from './arrow.svg'; // Vue 组件
194+
import arrowSvg from './arrow.svg?raw'; // 原始字符串
195+
import arrowUrl from './arrow.svg?url'; // 文件 URL
196+
import arrowInline from './arrow.svg?inline'; // Base64 内联
197+
```
198+
190199
> 注意: 配置 include 后,其他 svg rule 规则将忽略该插件所配置的 include 的资源。
191200
192201
### 配置选项
193202

194-
| 选项 | 类型 | 默认值 | 说明 |
195-
| ------- | ------ | --------- | ---------------- |
196-
| test | RegExp | /\\.svg$/ | 匹配要处理的文件 |
197-
| include | RegExp | null | 仅包含匹配的目录 |
198-
| exclude | RegExp | null | 排除匹配的目录 |
203+
| 选项 | 类型 | 默认值 | 说明 |
204+
| ----------- | ------ | --------- | ----------------------------------------------------- |
205+
| test | RegExp | /\\.svg$/ | 匹配要处理的文件 |
206+
| include | RegExp | null | 仅包含匹配的目录 |
207+
| exclude | RegExp | null | 排除匹配的目录 |
208+
| rawQuery | String | 'raw' | 当资源包含此 query 参数时,返回原始 SVG 字符串 |
209+
| urlQuery | String | 'url' | 当资源包含此 query 参数时,返回 SVG 文件 URL |
210+
| inlineQuery | String | 'inline' | 当资源包含此 query 参数时,返回 base64 编码的内联内容 |
199211

200212
### 在 Vue 组件中使用
201213

@@ -271,7 +283,7 @@ module.exports = {
271283
## 🛠️ 兼容性
272284

273285
- **Vue**: 2.7+ / 3.0+
274-
- **构建工具**: Webpack / Rspack 1+ with Vue2 with vue-loader only
286+
- **构建工具**: Webpack 5/ Rspack 1
275287
- **浏览器**: 现代浏览器(支持 SVG `<symbol>``<use>` 元素)
276288

277289
---

0 commit comments

Comments
 (0)