JetBrains / svg-sprite-loader

Webpack loader for creating SVG sprites.
MIT License
2.01k stars 272 forks source link

Bug production mode replacement in plain mode not propagated #475

Closed netconomy-stephan-dum closed 2 years ago

netconomy-stephan-dum commented 2 years ago

What is the current behavior?

We are currently facing the issue that icons paths for external sprites are not getting replaced.

What is the expected behavior?

The svg url should be replaced with the correct one.

also overwriting _valueAsString will fix the issue:

function replaceInModuleSource(module, replacements) {
  const source = module._source;

  if (typeof source === 'string') {
    module._source = replaceSpritePlaceholder(source, replacements);
  } else if (typeof source === 'object' && typeof source._value === 'string') {
    source._value = replaceSpritePlaceholder(source._value, replacements);
    // this fixes the issue
    source._valueAsString = source._value;
    // not needed now but who knows
    source._valueAsBuffer = Buffer.from(source._value);
  }

  return module;
}

on top here is another improvement suggestion which is not mandatory. ;)

function replaceSpritePlaceholder(content, replacements) {
  let result = content;
  Object.keys(replacements)
    .forEach((subj) => {
      let re = new RegExp(escapeRegExpSpecialChars(subj), 'g');
      result = result.replace(re, replacements[subj]);

      if (isWindows) {
        re = new RegExp(escapeRegExpSpecialChars(subj), 'g');
        result = result.replace(/\\\\/g, '\\').replace(re, replacements[subj]);
      }
    });

  return result;

this could be refactored to

const replaceSpritePlaceholder = (content, replacements) => Object.keys(replacements).reduce(
  (result, subj) => result.replace(
    new RegExp(
      escapeRegExpSpecialChars(
        subj.replace(/\\/g, '\\\\')
      ),
      'g',
    ),
    replacements[subj]
  ),
  content
);

this avoids the side effect of removing to many \ from the result.

Please tell us about your environment: