image_optim icon indicating copy to clipboard operation
image_optim copied to clipboard

Add support for SVGo 2.x

Open mtancoigne opened this issue 4 years ago • 7 comments

Version 2 has CLI changes, which makes it incompatible with image_optim. I have not dug into the code to see how the different versions can be handled, but for now, I can say that a call like

optimizer = ImageOptim.new(svgo: { enable_plugins: %w[removeScriptElement removeStyleElement removeOffCanvasPaths removeRasterImages] })
optimizer.optimize_image! path

leaves the picture unchanged.

From the release notes:

Painful coa was replaced with well maintained commander.

--enable and --disable flags are removed. In later versions we will explore plugins setup via CLI.

Inlined json config is no longer suppored. CLI flags should be used instead.

--config="{multipass:true}"

By default SVGO CLI will search for svgo.config.js. --config flag allows to specify js config with any name.

YAML and JSON configuration is no longer supported for the sake of simplicity and less dependencies.

mtancoigne avatar Feb 22 '21 12:02 mtancoigne

From the 2.x CLI: svgo --help

Usage: svgo [options] [INPUT...]

Nodejs-based tool for optimizing SVG vector graphics files

Arguments:
  INPUT                      Alias to --input

Options:
  [...]
  --config <CONFIG>          Config file or JSON string to extend or replace default
  [...]

So it seems that the plugins should be enabled/disabled in a JSON string passed to the --config argument, as for version 1.3.x. I'm looking at the format to see if it's compatible.

mtancoigne avatar Feb 22 '21 13:02 mtancoigne

As per the README, about JSON configuration, "If plugins field is specified default list is fully overrided". The other possibility would be to use a javascript configuration file to keep the default plugins, and create a json from scratch if file does not exist... which is, IMO, not optimal.

mtancoigne avatar Feb 22 '21 13:02 mtancoigne

Thanks for opening the issue. Checking release 2.0.0 there is a note about using extendDefaultPlugins([…]) and active: false to disable default plugin, so it should be possible to make it work without creating config file.

toy avatar Feb 22 '21 17:02 toy

extendDefaultPlugins([…]) is available in JS configuration files, as the methods returns the default list. I'm not sure SVGo handles raw javascript from the --config option. I'll check this

mtancoigne avatar Feb 22 '21 18:02 mtancoigne

Well... passing raw JSON in the CLI does nothing. SVGo ignores it:

node_modules/.bin/svgo -i in.svg -o defaults.svg --pretty
node_modules/.bin/svgo -i in.svg -o out.svg --pretty --config="{floatPrecision:1}"
diff defaults.svg out.svg
# no difference

# With svgo.config.js and the same options
node_modules/.bin/svgo -i in.svg -o out.svg --pretty
diff defaults.svg out.svg
# lots of differences

Passing raw javascript is silently ignored, as I thought:

node_modules/.bin/svgo -i in.svg -o out.svg --pretty --config="module.exports={floatPrecision:1};"
diff defaults.svg out.svg
# no difference

While not evaluating JS from --config seems a good thing, the fact that SVGo silently ignores the content of --config while its manual states "Config file or JSON string" is clearly an issue. I'll open one on the project.

mtancoigne avatar Feb 22 '21 19:02 mtancoigne

They dropped support for inline JSON in '--config', it now only takes a JS file as argument. I guess we're stuck with v 1.3 for now, or specify a configuration file or have a svgo.config.js file in our projects.

mtancoigne avatar Feb 23 '21 05:02 mtancoigne

You already saw that in 2.1.0 properly documents that config can be only a js file path. The solution would be to detect svgo >= 2 and create a temp config file if enabled/disabled were used (but one for the worker, not for every optimised svg file). I'm trying to think about the problems of such solution.

toy avatar Feb 24 '21 15:02 toy