4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/.vuepress/Example.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
31 |
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | vue-svg-loader
3 | webpack loader that lets you use SVG files as Vue components
4 |
5 | Documentation -
6 | FAQ
7 |
8 |
9 | ## Installation
10 | ``` bash
11 | npm i -D vue-svg-loader@beta
12 |
13 | yarn add --dev vue-svg-loader@beta
14 | ```
15 |
16 | ## Basic configuration
17 | ### webpack
18 | ``` js
19 | module.exports = {
20 | module: {
21 | rules: [
22 | {
23 | test: /\.svg$/,
24 | use: [
25 | 'vue-loader',
26 | 'vue-svg-loader',
27 | ],
28 | },
29 | ],
30 | },
31 | };
32 | ```
33 | ### Vue CLI
34 | ``` js
35 | module.exports = {
36 | chainWebpack: (config) => {
37 | const svgRule = config.module.rule('svg');
38 |
39 | svgRule.uses.clear();
40 |
41 | svgRule
42 | .use('vue-loader')
43 | .loader('vue-loader') // or `vue-loader-v16` if you are using a preview support of Vue 3 in Vue CLI
44 | .end()
45 | .use('vue-svg-loader')
46 | .loader('vue-svg-loader');
47 | },
48 | };
49 | ```
50 |
51 | ### Nuxt.js (1.x / 2.x)
52 | ``` js
53 | module.exports = {
54 | build: {
55 | extend: (config) => {
56 | const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
57 |
58 | svgRule.test = /\.(png|jpe?g|gif|webp)$/;
59 |
60 | config.module.rules.push({
61 | test: /\.svg$/,
62 | use: [
63 | 'vue-loader',
64 | 'vue-svg-loader',
65 | ],
66 | });
67 | },
68 | },
69 | };
70 | ```
71 |
72 | ## Example usage
73 | ``` vue
74 |
75 |
89 |
90 |
104 | ```
105 |
106 | ## License
107 | [](https://app.fossa.io/projects/git%2Bgithub.com%2Fvisualfanatic%2Fvue-svg-loader?ref=badge_large)
108 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroText: vue-svg-loader
4 | heroImage: /logo.svg
5 | actionText: Example →
6 | tagline: Use SVG files as Vue components
7 | actionLink: /#example
8 | features:
9 | - title: Easily styleable
10 | details: This loader inlines the SVGs which enables you to style aspects like for example stroke/fill color.
11 | - title: Optimized
12 | details: Each SVG you import is optimized on-the-fly using powerful SVGO without you having to do anything.
13 | - title: SSR ready
14 | details: You can import the SVG components inside the code that is going to be rendered on the server side.
15 | ---
16 |
17 | ## Installation
18 |
19 |
20 |
21 |
22 | ``` bash
23 | yarn add -D vue-svg-loader@beta
24 | ```
25 |
26 |
27 |
28 |
29 | ``` bash
30 | npm i -D vue-svg-loader@beta
31 | ```
32 |
33 |
34 |
35 |
36 | ## Configuration
37 |
38 |
39 |
40 |
41 | ::: warning
42 | Make sure that your current configuration is not already processing the SVG files.
43 | Check this [FAQ](/faq.html#how-to-use-both-inline-and-external-svgs) section if you want to use both inline and external SVGs.
44 | :::
45 |
46 | ``` js
47 | module.exports = {
48 | module: {
49 | rules: [
50 | {
51 | test: /\.svg$/,
52 | use: ['vue-loader', 'vue-svg-loader'],
53 | },
54 | ],
55 | },
56 | };
57 | ```
58 |
59 |
60 |
61 |
62 | By default Vue CLI uses the `file-loader` to process the SVG files, you can replace it in `vue.config.js`:
63 |
64 | ``` js
65 | module.exports = {
66 | chainWebpack: (config) => {
67 | const svgRule = config.module.rule('svg');
68 |
69 | svgRule.uses.clear();
70 |
71 | svgRule
72 | .use('vue-loader')
73 | .loader('vue-loader')
74 | .end()
75 | .use('vue-svg-loader')
76 | .loader('vue-svg-loader');
77 | },
78 | };
79 | ```
80 |
81 |
82 |
83 |
84 | Similarly to Vue CLI, you need to modify existing rule (in `nuxt.config.js`) that processes the SVG files:
85 |
86 | ``` js
87 | module.exports = {
88 | build: {
89 | extend: (config) => {
90 | const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
91 |
92 | svgRule.test = /\.(png|jpe?g|gif|webp)$/;
93 |
94 | config.module.rules.push({
95 | test: /\.svg$/,
96 | use: ['vue-loader', 'vue-svg-loader'],
97 | });
98 | },
99 | },
100 | };
101 | ```
102 |
103 |
104 |
105 |
106 | ## Example
107 |
108 | ### Preview
109 |
110 |
111 |
112 | ### Code
113 |
114 | <<< @/docs/.vuepress/Example.vue{4,8,12,18-20,25-27}
115 |
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar: auto
3 | ---
4 |
5 | # Frequently Asked Questions
6 |
7 | ## How to use both inline and external SVGs?
8 |
9 |
10 |
11 |
12 | ``` js
13 | module.exports = {
14 | module: {
15 | rules: [
16 | {
17 | test: /\.svg$/,
18 | oneOf: [
19 | {
20 | resourceQuery: /inline/,
21 | use: [
22 | 'vue-loader',
23 | 'vue-svg-loader',
24 | ],
25 | },
26 | {
27 | loader: 'file-loader',
28 | query: {
29 | name: 'assets/[name].[hash:8].[ext]',
30 | },
31 | },
32 | ],
33 | },
34 | ],
35 | },
36 | };
37 | ```
38 |
39 |
40 |
41 |
42 | ``` js
43 | module.exports = {
44 | chainWebpack: (config) => {
45 | const svgRule = config.module.rule('svg');
46 |
47 | svgRule.uses.clear();
48 |
49 | svgRule
50 | .oneOf('inline')
51 | .resourceQuery(/inline/)
52 | .use('vue-loader')
53 | .loader('vue-loader')
54 | .end()
55 | .use('vue-svg-loader')
56 | .loader('vue-svg-loader')
57 | .end()
58 | .end()
59 | .oneOf('external')
60 | .use('file-loader')
61 | .loader('file-loader')
62 | .options({
63 | name: 'assets/[name].[hash:8].[ext]',
64 | });
65 | },
66 | };
67 | ```
68 |
69 |
70 |
71 |
72 | ``` js
73 | module.exports = {
74 | build: {
75 | extend: (config) => {
76 | const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
77 |
78 | svgRule.test = /\.(png|jpe?g|gif|webp)$/;
79 |
80 | config.module.rules.push({
81 | test: /\.svg$/,
82 | oneOf: [
83 | {
84 | resourceQuery: /inline/,
85 | use: [
86 | 'vue-loader',
87 | 'vue-svg-loader',
88 | ],
89 | },
90 | {
91 | loader: 'file-loader',
92 | query: {
93 | name: 'assets/[name].[hash:8].[ext]',
94 | },
95 | },
96 | ],
97 | });
98 | },
99 | },
100 | };
101 | ```
102 |
103 |
104 |
105 |
106 | ``` vue
107 |
108 |
109 |
110 |
![]()
111 |
112 |
113 |
114 |
130 |
135 | ```
136 |
137 | ## How to prefix `id` attributes?
138 | To avoid the situation where two or more SVGs are using the same `id` attribute, you can use the `prefixIds` option provided by `SVGO`.
139 |
140 |
141 |
142 |
143 | ``` js
144 | module.exports = {
145 | module: {
146 | rules: [
147 | {
148 | test: /\.svg$/,
149 | use: [
150 | 'vue-loader',
151 | {
152 | loader: 'vue-svg-loader',
153 | options: {
154 | svgo: {
155 | plugins: [
156 | { prefixIds: true },
157 | ],
158 | },
159 | },
160 | },
161 | ],
162 | },
163 | ],
164 | },
165 | };
166 | ```
167 |
168 |
169 |
170 |
171 | ``` js
172 | module.exports = {
173 | chainWebpack: (config) => {
174 | const svgRule = config.module.rule('svg');
175 |
176 | svgRule.uses.clear();
177 |
178 | svgRule
179 | .use('vue-loader')
180 | .loader('vue-loader')
181 | .end()
182 | .use('vue-svg-loader')
183 | .loader('vue-svg-loader')
184 | .options({
185 | svgo: {
186 | plugins: [
187 | { prefixIds: true },
188 | ],
189 | },
190 | });
191 | },
192 | };
193 | ```
194 |
195 |
196 |
197 |
198 | ``` js
199 | module.exports = {
200 | build: {
201 | extend: (config) => {
202 | const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
203 |
204 | svgRule.test = /\.(png|jpe?g|gif|webp)$/;
205 |
206 | config.module.rules.push({
207 | test: /\.svg$/,
208 | use: [
209 | 'vue-loader',
210 | {
211 | loader: 'vue-svg-loader',
212 | options: {
213 | svgo: {
214 | plugins: [
215 | { prefixIds: true },
216 | ],
217 | },
218 | },
219 | },
220 | ],
221 | });
222 | },
223 | },
224 | };
225 | ```
226 |
227 |
228 |
229 |
230 | If you want to customize generated IDs, you can pass a function instead of `true` to the `prefixIds` plugin.
231 | Here is an example for generating IDs that are prefixed by the file name:
232 |
233 |
234 |
235 |
236 | ``` js
237 | const { basename } = require('path');
238 |
239 | module.exports = {
240 | module: {
241 | rules: [
242 | {
243 | test: /\.svg$/,
244 | use: [
245 | 'vue-loader',
246 | {
247 | loader: 'vue-svg-loader',
248 | options: {
249 | svgo: {
250 | plugins: [
251 | {
252 | prefixIds: {
253 | prefix: (node, { path }) => basename(path, '.svg'),
254 | delim: '-',
255 | },
256 | },
257 | ],
258 | },
259 | },
260 | },
261 | ],
262 | },
263 | ],
264 | },
265 | };
266 | ```
267 |
268 |
269 |
270 |
271 | ``` js
272 | const { basename } = require('path');
273 |
274 | module.exports = {
275 | chainWebpack: (config) => {
276 | const svgRule = config.module.rule('svg');
277 |
278 | svgRule.uses.clear();
279 |
280 | svgRule
281 | .use('vue-loader')
282 | .loader('vue-loader')
283 | .end()
284 | .use('vue-svg-loader')
285 | .loader('vue-svg-loader')
286 | .options({
287 | svgo: {
288 | plugins: [
289 | {
290 | prefixIds: {
291 | prefix: (node, { path }) => basename(path, '.svg'),
292 | delim: '-',
293 | },
294 | },
295 | ],
296 | },
297 | });
298 | },
299 | };
300 | ```
301 |
302 |
303 |
304 |
305 | ``` js
306 | const { basename } = require('path');
307 |
308 | module.exports = {
309 | build: {
310 | extend: (config) => {
311 | const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
312 |
313 | svgRule.test = /\.(png|jpe?g|gif|webp)$/;
314 |
315 | config.module.rules.push({
316 | test: /\.svg$/,
317 | use: [
318 | 'vue-loader',
319 | {
320 | loader: 'vue-svg-loader',
321 | options: {
322 | svgo: {
323 | plugins: [
324 | {
325 | prefixIds: {
326 | prefix: (node, { path }) => basename(path, '.svg'),
327 | delim: '-',
328 | },
329 | },
330 | ],
331 | },
332 | },
333 | },
334 | ],
335 | });
336 | },
337 | },
338 | };
339 | ```
340 |
341 |
342 |
343 |
344 |
345 | ## How to use this loader with TypeScript?
346 |
347 | If you want to use this loader in a project that is written in TypeScript, you will get the "Cannot find module" error.
348 | To fix that you need to provide a type definition which is needed by TypeScript to know how to handle SVG components.
349 |
350 | ``` ts
351 | declare module '*.svg' {
352 | import Vue, {VueConstructor} from 'vue';
353 | const content: VueConstructor;
354 | export default content;
355 | }
356 | ```
357 |
358 | ## How to use this loader with Jest?
359 |
360 | There is one major issue when it comes to integrating vue-svg-loader with Jest, and it is async behaviour. Jest's transforms are synchronous, webpack loaders can be both. That means we cannot use SVGO to process the SVG files, which can be bad in some cases. It is always good idea to always pass the SVG files through SVGO before putting them in a project [(for example using this great tool)](https://jakearchibald.github.io/svgomg/), so that the end result does not contain:
361 |
362 | - XML declaration,
363 | - `