diff --git a/README.md b/README.md index 6cb2a98..fb7ea09 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,16 @@ minify: - **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array. - Exclude `*.min.svg` by default. - **plugins** - Plugin options. - - Example: to retain comments, `plugins: [{removeComments: false}]`. + - Examples: + ``` yaml + plugins: + # Retain comments + - name: 'removeComments' + active: false + # Do not remove unused ID attributes + - name: 'cleanupIDs' + active: false + ``` - For more options, see [svgo](https://github.com/svg/svgo). - **globOptions** - See [globbing](#globbing) section. diff --git a/index.js b/index.js index ab0efb9..ba9f281 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,8 @@ /* global hexo */ 'use strict' +const { extendDefaultPlugins } = require('svgo') + hexo.config.minify = Object.assign({ enable: true }, hexo.config.minify) @@ -48,7 +50,7 @@ hexo.config.minify.svg = Object.assign({ priority: 10, verbose: false, include: ['*.svg', '!*.min.svg'], - plugins: [], + plugins: extendDefaultPlugins([]), globOptions: { basename: true } }, hexo.config.minify.svg) diff --git a/lib/filter.js b/lib/filter.js index c41f46b..5d7371b 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -3,7 +3,7 @@ const { minify: htmlMinify } = require('html-minifier') const CleanCSS = require('clean-css') const { minify: terserMinify } = require('terser') -const Svgo = require('svgo') +const { optimize: svgOptimize, extendDefaultPlugins } = require('svgo') const zlib = require('zlib') const { promisify } = require('util') const gzip = promisify(zlib.gzip) @@ -136,6 +136,7 @@ function minifySvg () { const { route } = hexo const routeList = route.list() const { globOptions, include, verbose } = options + const plugins = Array.isArray(options.plugins) ? extendDefaultPlugins(options.plugins) : extendDefaultPlugins([]) return Promise.all((match(routeList, include, globOptions)).map((path) => { return new Promise((resolve, reject) => { @@ -144,12 +145,12 @@ function minifySvg () { assetPath.on('data', (chunk) => (assetTxt += chunk)) assetPath.on('end', async () => { if (assetTxt.length) { - try { - const { data } = await new Svgo(options).optimize(assetTxt) + const { data, error } = svgOptimize(assetTxt, { ...options, plugins }) + if (data) { if (verbose) logFn.call(this, assetTxt, data, path, 'svg') resolve(route.set(path, data)) - } catch (err) { - reject(new Error(`Path: ${path}\n${err}`)) + } else if (error) { + reject(new Error(`Path: ${path}\n${error}`)) } } resolve() diff --git a/package.json b/package.json index 33a5b14..be767d8 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "html-minifier": "^4.0.0", "micromatch": "^4.0.2", "minify-xml": "^2.1.1", - "svgo": "^1.2.2", + "svgo": "^2.3.0", "terser": "^5.3.0" }, "devDependencies": { diff --git a/test/svg.test.js b/test/svg.test.js index 218843c..0cfc0fe 100644 --- a/test/svg.test.js +++ b/test/svg.test.js @@ -2,7 +2,7 @@ 'use strict' const Hexo = require('hexo') -const Svgo = require('svgo') +const { optimize: svgOptimize, extendDefaultPlugins } = require('svgo') describe('svg', () => { const hexo = new Hexo(__dirname) @@ -16,7 +16,7 @@ describe('svg', () => { enable: true, verbose: false, include: ['*.svg', '!*.min.svg'], - plugins: [], + plugins: extendDefaultPlugins([]), globOptions: { basename: true } } } @@ -30,7 +30,7 @@ describe('svg', () => { test('default', async () => { await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, hexo.config.minify.svg) const output = hexo.route.get(path) let result = '' @@ -57,10 +57,13 @@ describe('svg', () => { }) test('option', async () => { - const customOpt = [{ cleanupIDs: false }] + const customOpt = [{ + name: 'cleanupIDs', + active: false + }] hexo.config.minify.svg.plugins = customOpt await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, { ...hexo.config.minify.svg, plugins: extendDefaultPlugins(customOpt) }) const output = hexo.route.get(path) let result = '' @@ -79,17 +82,27 @@ describe('svg', () => { expect(hexo.log.log.mock.calls[0][0]).toContain(`svg: ${path}`) }) + test('option - plugins - invalid', async () => { + hexo.config.minify.svg.plugins = 'invalid' + await s() + const { data } = svgOptimize(input, { ...hexo.config.minify.svg, plugins: extendDefaultPlugins([]) }) + + const output = hexo.route.get(path) + let result = '' + output.on('data', (chunk) => (result += chunk)) + output.on('end', () => { + expect(result).toBe(data) + }) + }) + test('invalid svg', async () => { const input = '{}' hexo.route.set(path, input) - let expected - try { - await new Svgo(hexo.config.minify.svg).optimize(input) - } catch (err) { - expected = err - } - expect(expected).toBeDefined() - await expect(s()).rejects.toThrow(`Path: ${path}\n${expected}`) + + const { error } = svgOptimize(input, hexo.config.minify.svg) + + expect(error).toBeDefined() + await expect(s()).rejects.toThrow(`Path: ${path}\n${error}`) }) test('include - exclude *.min.svg by default', async () => { @@ -110,7 +123,7 @@ describe('svg', () => { const path = 'foo/bar.svg' hexo.route.set(path, input) await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, hexo.config.minify.svg) const output = hexo.route.get(path) let result = '' @@ -125,7 +138,7 @@ describe('svg', () => { const path = 'eleifend/lectus/nullam/dapibus/netus.svg' hexo.route.set(path, input) await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, hexo.config.minify.svg) const output = hexo.route.get(path) let result = '' @@ -153,7 +166,7 @@ describe('svg', () => { hexo.route.set(inpath, input) }) await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, hexo.config.minify.svg) const minPaths = paths.slice(0, 2) const unminPaths = paths.slice(2) @@ -197,7 +210,7 @@ describe('svg', () => { hexo.route.set(inpath, input) }) await s() - const { data } = await new Svgo(hexo.config.minify.svg).optimize(input) + const { data } = svgOptimize(input, hexo.config.minify.svg) paths.forEach((inpath) => { const output = hexo.route.get(inpath)