-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
140 lines (128 loc) · 3.74 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const loaderUtils = require('loader-utils');
const { optimize } = require('svgo');
const { validate } = require('schema-utils');
const svgSpriteState = require('./utils/spriteState');
const transformSvg = require('./utils/transformSvg');
const optionsSchema = {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'SvgSpriteGeneratorPlugin Options',
type: 'object',
properties: {
symbolId: {
description:
'Sprite item (single icon) `<symbol>` id attribute value. Can be a string or a function that takes the file path of the original icon and returns a string.',
oneOf: [
{
type: 'string',
description:
"String value for symbol id, e.g. '[name]' which defaults to the icon filename without extension.",
},
{
instanceof: 'Function',
description:
'Function that takes the file path of the original icon and returns a string.',
},
],
},
spriteFilePath: {
type: 'string',
description:
'Path to sprite file. This path is relative to `webpack.output.path` and can include [interpolateName](https://github.com/webpack/loader-utils#interpolatename) patterns.',
},
svgoOptimize: {
description: 'Enable or disable SVG optimization',
oneOf: [
{
type: 'boolean',
description:
'Enable or disable SVG optimization with default settings.',
},
{
type: 'object',
description: 'Customize SVG optimization using svgo options.',
properties: {
plugins: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the svgo plugin',
},
params: {
type: 'object',
description: 'Parameters for the svgo plugin',
},
},
required: ['name'],
},
},
},
},
],
},
addContent: {
type: 'boolean',
description:
'Add SVG content as property to transformed SVG object, which may increase bundle size.',
},
},
required: [],
additionalProperties: false,
};
function svgSpriteGenerationLoader(source) {
const options = {
symbolId: '[name]',
spriteFilePath: 'sprite.svg',
svgoOptimize: true,
addContent: false,
...this.getOptions(),
};
validate(optionsSchema, options, {
name: 'svgSpriteGenerationLoader',
baseDataPath: 'options',
});
this.cacheable(false);
const isSvgoOptimizeEnabled = !!options.svgoOptimize;
const svgoOptimizeConfig =
options.svgoOptimize === true
? {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
},
},
},
'removeXMLNS',
],
}
: options.svgoOptimize;
const iconSource = isSvgoOptimizeEnabled
? optimize(source, svgoOptimizeConfig).data
: source;
const { attributes, content } = transformSvg(iconSource);
const symbolId = loaderUtils.interpolateName(
this,
typeof options.symbolId === 'string'
? options.symbolId
: options.symbolId(this.resourcePath)
);
if (this.target === 'web') {
svgSpriteState.addSpriteIcon(
{ symbolId, attributes, content },
options.spriteFilePath
);
}
return `
export default ${JSON.stringify({
symbolId,
attributes,
...(options.addContent ? { content } : {}),
})}
`;
}
module.exports = svgSpriteGenerationLoader;