UNPKG

2.76 kBJavaScriptView Raw
1const { interpolateName, getOptions } = require('loader-utils');
2const urlSlug = require('url-slug');
3const SVGCompiler = require('svg-baker');
4
5const { NAMESPACE } = require('./config');
6const configure = require('./configurator');
7const { getWebpackVersion } = require('./utils');
8const Exceptions = require('./exceptions');
9
10let svgCompiler = new SVGCompiler();
11
12// eslint-disable-next-line consistent-return
13module.exports = function loader(content) {
14 if (this.cacheable) {
15 this.cacheable();
16 }
17
18 const done = this.async();
19 const loaderContext = this;
20 const { resourcePath, rootContext, loaderIndex } = loaderContext;
21 // webpack 1 compat
22 const resourceQuery = loaderContext.resourceQuery || '';
23 const compiler = loaderContext._compiler;
24 const isChildCompiler = compiler.isChild();
25 const parentCompiler = isChildCompiler ? compiler.parentCompilation.compiler : null;
26 const matchedRules = getOptions(loaderContext);
27
28 if (!content.includes('<svg')) {
29 throw new Exceptions.InvalidSvg(content, matchedRules);
30 }
31
32 const configObj = { context: loaderContext };
33
34 if (getWebpackVersion.IS_4) {
35 configObj.config = loaderContext.query;
36 configObj.target = loaderContext.target;
37 } else {
38 configObj.config = matchedRules;
39 configObj.target = loaderContext.options.target || loaderContext.target;
40 }
41
42 /**
43 * @type {SVGSpriteLoaderConfig}
44 */
45 const config = configure(configObj);
46
47 if (config.extract) {
48 const plugin = parentCompiler
49 ? parentCompiler.options.plugins.find(p => p.NAMESPACE && p.NAMESPACE === NAMESPACE)
50 : this[NAMESPACE];
51
52 if (typeof plugin === 'undefined') {
53 throw new Exceptions.ExtractPluginMissingException();
54 }
55
56 if (loaderIndex > 0) {
57 this.emitWarning(new Exceptions.RemainingLoadersInExtractModeException());
58 }
59
60 svgCompiler = plugin.svgCompiler;
61 }
62
63 let runtimeGenerator;
64 try {
65 runtimeGenerator = require(config.runtimeGenerator); // eslint-disable-line import/no-dynamic-require,global-require
66 } catch (e) {
67 throw new Exceptions.InvalidRuntimeException(e.message);
68 }
69
70 let id;
71 if (typeof config.symbolId === 'function') {
72 id = config.symbolId(resourcePath, resourceQuery);
73 } else {
74 const idPattern = config.symbolId + (resourceQuery ? `--${urlSlug(resourceQuery)}` : '');
75 id = interpolateName(loaderContext, idPattern, {
76 content,
77 context: compiler.context,
78 regExp: config.symbolRegExp
79 });
80 }
81 svgCompiler.addSymbol({ id, content, path: resourcePath + resourceQuery })
82 .then((symbol) => {
83 const runtime = runtimeGenerator({ symbol, config, context: rootContext, loaderContext });
84 done(null, runtime);
85 }).catch(done);
86};
87
88module.exports.NAMESPACE = NAMESPACE;