loader.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. const { interpolateName, getOptions } = require('loader-utils');
  2. const urlSlug = require('url-slug');
  3. const SVGCompiler = require('svg-baker');
  4. const { NAMESPACE } = require('./config');
  5. const configure = require('./configurator');
  6. const utils = require('./utils');
  7. const Exceptions = require('./exceptions');
  8. let svgCompiler = new SVGCompiler();
  9. // eslint-disable-next-line consistent-return
  10. module.exports = function loader(content) {
  11. this.cacheable();
  12. const done = this.async();
  13. const loaderContext = this;
  14. const { resourcePath, resource, context, loaderIndex } = loaderContext;
  15. // webpack 1 compat
  16. const resourceQuery = loaderContext.resourceQuery || '';
  17. const compiler = loaderContext._compiler;
  18. const isChildCompiler = compiler.isChild();
  19. const parentCompiler = isChildCompiler ? compiler.parentCompilation.compiler : null;
  20. /**
  21. * @type {SVGSpriteLoaderConfig}
  22. */
  23. const config = configure({
  24. config: getOptions(loaderContext),
  25. context: loaderContext
  26. });
  27. if (config.extract) {
  28. const plugin = parentCompiler
  29. ? parentCompiler.options.plugins.find(p => p.NAMESPACE && p.NAMESPACE === NAMESPACE)
  30. : this[NAMESPACE];
  31. if (typeof plugin === 'undefined') {
  32. throw new Exceptions.ExtractPluginMissingException();
  33. }
  34. if (loaderIndex > 0) {
  35. this.emitWarning(new Exceptions.RemainingLoadersInExtractModeException());
  36. }
  37. svgCompiler = plugin.svgCompiler;
  38. }
  39. let runtimeGenerator;
  40. try {
  41. runtimeGenerator = require(config.runtimeGenerator); // eslint-disable-line import/no-dynamic-require,global-require
  42. } catch (e) {
  43. throw new Exceptions.InvalidRuntimeException(config.runtimeGenerator);
  44. }
  45. const matchedRules = utils.getMatchedRules(resource, utils.getLoadersRules(compiler));
  46. if (matchedRules.length > 1 && !compiler.isChild()) {
  47. this.emitWarning(new Exceptions.SeveralRulesAppliedException(resource, matchedRules));
  48. }
  49. const idPattern = config.symbolId + (resourceQuery ? `--${urlSlug(resourceQuery)}` : '');
  50. const id = interpolateName(loaderContext, idPattern, { content, context });
  51. svgCompiler.addSymbol({ id, content, path: resourcePath + resourceQuery })
  52. .then((symbol) => {
  53. const runtime = runtimeGenerator({ symbol, config, context, loaderContext });
  54. done(null, runtime);
  55. }).catch(done);
  56. };
  57. module.exports.NAMESPACE = NAMESPACE;