svg-sprite-loader icon indicating copy to clipboard operation
svg-sprite-loader copied to clipboard

Disable runtime configuration completely?

Open freezy opened this issue 7 years ago • 9 comments

Do you want to request a feature, report a bug or ask a question? Ask a question

What is the current behavior? SVGs get extracted and injected into my template, but there is ~30kb of additional code in my bundle: image

What is the expected behavior? I don't import any icons in code, they are exclusively used in the templates. It's unused code I'd like to avoid shipping.

If the current behavior is a bug, please provide the steps to reproduce, at least part of webpack config with loader configuration and piece of your code. My relevant config:

const iconsContext = resolve(__dirname, '../src/icons');
module.exports = {
   module: {
      rules: [
         { test: /\.svg$/, use: [
            { loader: 'svg-sprite-loader', options: { extract: true } },
            { loader: 'svgo-loader', options: { plugins: [ { removeDoctype: true }, { removeXMLProcInst: true }, { removeComments: true }, { removeMetadata: true }, { removeEditorsNSData: true }, { cleanupAttrs: true }, { convertStyleToAttrs: true }, { removeRasterImages: true }, { cleanupNumericValues: true }, { convertColors: true }, { removeUnknownsAndDefaults: true }, { removeNonInheritableGroupAttrs: true }, { removeUselessStrokeAndFill: true }, { removeViewBox: true }, { cleanupEnableBackground: true }, { removeHiddenElems: true }, { removeEmptyText: true }, { convertShapeToPath: true }, { moveElemsAttrsToGroup: true }, { moveGroupAttrsToElems: true }, { collapseGroups: true }, { convertPathData: true }, { convertTransform: true }, { removeEmptyAttrs: true }, { removeEmptyContainers: true }, { mergePaths: true }, { cleanupIDs: true }, { removeUnusedNS: true }, { transformsWithOnePath: false }, { sortAttrs: true }, { removeTitle: true } ] } }
         ], include: iconsContext },
      ],
      plugins: [
         new SpriteLoaderPlugin({ plainSprite: true })
      ]
   }
}

If you want to reproduce, here's my repo (it's not minimal though):

git clone https://github.com/vpdb/website.git vpdb-website
cd vpdb-website && npm install
npm run build:analyze

Please tell us about your environment:

  • Node.js version: v8.9.1
  • webpack version: 4.4.1
  • svg-sprite-loader version: 3.7.3
  • OS type & version: Windows 10 x64

I've tried setting runtimeGenerator to null, but that obviously didn't work. Maybe this is achievable in any other way, otherwise I would welcome an option to only extract without bloating the JavaScript bundle.

freezy avatar Apr 03 '18 18:04 freezy

You're right, extract runtime is not optimal, because it contains symbol id, viewBox etc. As quick workaround you can write own runtime generator which returns only path to symbol:

extract-runtime-generator.js

module.exports = function runtimeGenerator({ symbol }) {
  return `export default __webpack_public_path__ + ${JSON.stringify(symbol.request.file)}`;
};

And setup it in loader config:

{
	loader: 'svg-sprite-loader', options: {
		runtimeGenerator: require.resolve('runtime-generator-path'),
		extract: true
	}
}

kisenka avatar Apr 03 '18 19:04 kisenka

@freezy does my solution fit you needs?

kisenka avatar May 01 '18 10:05 kisenka

Yes, sorry for not getting back to you earlier. I've tried your suggestion, and while the produced script is now smaller (18k minified), it's still there:

freezy avatar May 01 '18 10:05 freezy

And what about production mode?

kisenka avatar May 01 '18 10:05 kisenka

It's already production mode (Wepack config { mode: "production" } if that's what you're referring to).

freezy avatar May 01 '18 11:05 freezy

I've pushed your proposition to the repo mentioned in the description if you want to reproduce.

freezy avatar May 01 '18 11:05 freezy

@kisenka There really should to be a way to turn this runtime stuff off. Most icon systems just need the SVGs to be added to the document with an ID, so they can be referenced with something like:

<svg viewBox="0 0 24 24">
  <use xlink:href="#icon-something"></use>
</svg>

That should not require more than a couple of lines of code to accomplish - and if any processing is needed, that really should happen at build time...

Edit:

I've updated my comment, as I just realized we're not talking about the gzipped size here, which is actually pretty small. I'm still wondering why it can't be even smaller though :-)

And more importantly, it seems this thing insists on creating its own chunk for the runtime, which means I'll have an extra HTTP request for no good reason - and that is a major problem, due to network latency. Any hints as to how this can be avoided?

thomas-darling avatar Feb 13 '19 19:02 thomas-darling

@freezy In execute mode you may add "null-loader", after "svg-sprite-loader". It removes runtime data from bundle(url, width, height, ets.), but still produce empty runtime function, and Warnings in console output "Some loaders will be applied after svg-sprite-loader in extract mode" But it save about 90% gziped code, and about 85% without gzip.

KhraksMamtsov avatar Aug 09 '19 08:08 KhraksMamtsov

Thanks, I'll try that!

freezy avatar Aug 09 '19 08:08 freezy