zhangjian
2023-06-05 0976d2d0f90cff460cedfdc8bd74e98c2c31a58c
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
const { interpolateName, getOptions } = require('loader-utils');
const urlSlug = require('url-slug');
const SVGCompiler = require('svg-baker');
 
const { NAMESPACE } = require('./config');
const configure = require('./configurator');
const Exceptions = require('./exceptions');
 
let svgCompiler = new SVGCompiler();
 
// eslint-disable-next-line consistent-return
module.exports = function loader(content) {
  if (this.cacheable) {
    this.cacheable();
  }
 
  const done = this.async();
  const loaderContext = this;
  const { resourcePath, loaderIndex } = loaderContext;
  // webpack 1 compat
  const resourceQuery = loaderContext.resourceQuery || '';
  const compiler = loaderContext._compiler;
  const isChildCompiler = compiler.isChild();
  const parentCompiler = isChildCompiler ? compiler.parentCompilation.compiler : null;
  const matchedRules = getOptions(loaderContext);
 
  if (!content.includes('<svg')) {
    throw new Exceptions.InvalidSvg(content, matchedRules);
  }
 
  const configObj = { context: loaderContext };
 
  configObj.config = matchedRules;
  configObj.target = loaderContext.target;
 
  /**
   * @type {SVGSpriteLoaderConfig}
   */
  const config = configure(configObj);
 
  if (config.extract) {
    const plugin = parentCompiler
      ? parentCompiler.options.plugins.find(p => p.NAMESPACE && p.NAMESPACE === NAMESPACE)
      : this[NAMESPACE];
 
    if (typeof plugin === 'undefined') {
      throw new Exceptions.ExtractPluginMissingException();
    }
 
    if (loaderIndex > 0) {
      this.emitWarning(new Exceptions.RemainingLoadersInExtractModeException());
    }
 
    svgCompiler = plugin.svgCompiler;
  }
 
  let runtimeGenerator;
  try {
    runtimeGenerator = require(config.runtimeGenerator); // eslint-disable-line import/no-dynamic-require,global-require
  } catch (e) {
    throw new Exceptions.InvalidRuntimeException(e.message);
  }
 
  let id;
  if (typeof config.symbolId === 'function') {
    id = config.symbolId(resourcePath, resourceQuery);
  } else {
    const idPattern = config.symbolId + (resourceQuery ? `--${urlSlug(resourceQuery)}` : '');
    id = interpolateName(loaderContext, idPattern, {
      content,
      context: compiler.context,
      regExp: config.symbolRegExp
    });
  }
  svgCompiler.addSymbol({ id, content, path: resourcePath + resourceQuery })
    .then((symbol) => {
      const runtime = runtimeGenerator({ symbol, config, context: loaderContext.context, loaderContext });
      done(null, runtime);
    }).catch(done);
};
 
module.exports.NAMESPACE = NAMESPACE;