diff --git a/README.md b/README.md
index 14805d23..c19917b8 100644
--- a/README.md
+++ b/README.md
@@ -199,7 +199,7 @@ You can find all default templates in [templates folder](https://github.com/smoo
## Node API usage
-SVGR can also be used programmatically:
+### `svgr(code, config, state)`
```js
import svgr from '@svgr/core'
@@ -218,6 +218,8 @@ svgr(svgCode, { icon: true }, { componentName: 'MyComponent' }).then(jsCode => {
})
```
+Use `svgr.sync(code, config, state)` if you would like to use sync version.
+
## [Webpack loader](https://github.com/smooth-code/svgr/blob/master/packages/webpack)
## [Rollup plugin](https://github.com/smooth-code/svgr/blob/master/packages/rollup)
diff --git a/packages/core/README.md b/packages/core/README.md
index 408bc90b..05bf7897 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -28,6 +28,8 @@ svgr(svgCode, { icon: true }, { componentName: 'MyComponent' }).then(jsCode => {
})
```
+Use `svgr.sync(code, config, state)` if you would like to use sync version.
+
## License
MIT
diff --git a/packages/core/src/__snapshots__/config.test.js.snap b/packages/core/src/__snapshots__/config.test.js.snap
new file mode 100644
index 00000000..b496b556
--- /dev/null
+++ b/packages/core/src/__snapshots__/config.test.js.snap
@@ -0,0 +1,199 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`svgo async #loadConfig [async] should load config using filePath 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
+
+exports[`svgo async #loadConfig [async] should not load config with "runtimeConfig: false 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+ "useRuntimeConfig": false,
+}
+`;
+
+exports[`svgo async #loadConfig [async] should use default config without state.filePath 1`] = `
+Object {
+ "dimensions": false,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": false,
+ "native": false,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": null,
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
+
+exports[`svgo async #loadConfig [async] should work with custom config path 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
+
+exports[`svgo sync #loadConfig [sync] should load config using filePath 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
+
+exports[`svgo sync #loadConfig [sync] should not load config with "runtimeConfig: false 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+ "useRuntimeConfig": false,
+}
+`;
+
+exports[`svgo sync #loadConfig [sync] should use default config without state.filePath 1`] = `
+Object {
+ "dimensions": false,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": false,
+ "native": false,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": null,
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
+
+exports[`svgo sync #loadConfig [sync] should work with custom config path 1`] = `
+Object {
+ "dimensions": true,
+ "expandProps": "end",
+ "h2xConfig": null,
+ "icon": true,
+ "native": false,
+ "noSemi": true,
+ "prettier": true,
+ "prettierConfig": null,
+ "ref": false,
+ "replaceAttrValues": Array [
+ Array [
+ "#063855",
+ "currentColor",
+ ],
+ ],
+ "runtimeConfig": true,
+ "svgProps": null,
+ "svgo": true,
+ "svgoConfig": null,
+ "template": null,
+ "titleProp": false,
+}
+`;
diff --git a/packages/core/src/config.js b/packages/core/src/config.js
index 439e325f..c7e9ebfd 100644
--- a/packages/core/src/config.js
+++ b/packages/core/src/config.js
@@ -33,11 +33,25 @@ export async function resolveConfig(searchFrom, configFile) {
return result ? result.config : null
}
+resolveConfig.sync = (searchFrom, configFile) => {
+ if (configFile == null) {
+ const result = explorer.searchSync(searchFrom)
+ return result ? result.config : null
+ }
+ const result = explorer.loadSync(configFile)
+ return result ? result.config : null
+}
+
export async function resolveConfigFile(filePath) {
const result = await explorer.search(filePath)
return result ? result.filepath : null
}
+resolveConfigFile.sync = filePath => {
+ const result = explorer.searchSync(filePath)
+ return result ? result.filepath : null
+}
+
export async function loadConfig({ configFile, ...baseConfig }, state = {}) {
const rcConfig =
state.filePath && baseConfig.runtimeConfig !== false
@@ -45,3 +59,11 @@ export async function loadConfig({ configFile, ...baseConfig }, state = {}) {
: {}
return { ...DEFAULT_CONFIG, ...rcConfig, ...baseConfig }
}
+
+loadConfig.sync = ({ configFile, ...baseConfig }, state = {}) => {
+ const rcConfig =
+ state.filePath && baseConfig.runtimeConfig !== false
+ ? resolveConfig.sync(state.filePath, configFile)
+ : {}
+ return { ...DEFAULT_CONFIG, ...rcConfig, ...baseConfig }
+}
diff --git a/packages/core/src/config.test.js b/packages/core/src/config.test.js
index 89c64c40..11379a0d 100644
--- a/packages/core/src/config.test.js
+++ b/packages/core/src/config.test.js
@@ -1,158 +1,71 @@
import path from 'path'
import { resolveConfig, resolveConfigFile, loadConfig } from './config'
-describe('config', () => {
- describe('#resolveConfig', () => {
- it('should return null if no config found', async () => {
- const config = await resolveConfig('/tmp')
- expect(config).toBe(null)
- })
+const getMethod = (method, mode) => (mode === 'sync' ? method.sync : method)
- it('should return config if found', async () => {
- const config = await resolveConfig(
- path.join(__dirname, '__fixtures__/svgr'),
- )
- expect(config).toEqual({
- icon: true,
- noSemi: true,
- replaceAttrValues: [['#063855', 'currentColor']],
+describe('svgo', () => {
+ describe.each([['sync'], ['async']])('%s', mode => {
+ describe(`#resolveConfig [${mode}]`, () => {
+ it('should return null if no config found', async () => {
+ const config = await getMethod(resolveConfig, mode)('/tmp')
+ expect(config).toBe(null)
})
- })
- })
- describe('#resolveConfigFile', () => {
- it('should return null if no config found', async () => {
- const config = await resolveConfigFile('/tmp')
- expect(config).toBe(null)
+ it('should return config if found', async () => {
+ const config = await getMethod(resolveConfig, mode)(
+ path.join(__dirname, '__fixtures__/svgr'),
+ )
+ expect(config).toEqual({
+ icon: true,
+ noSemi: true,
+ replaceAttrValues: [['#063855', 'currentColor']],
+ })
+ })
})
- it('should return config path if found', async () => {
- const config = await resolveConfigFile(
- path.join(__dirname, '__fixtures__/svgr'),
- )
- expect(config).toMatch(/__fixtures__(\/|\\)svgr(\/|\\)\.svgrrc$/)
- })
- })
+ describe(`#resolveConfigFile [${mode}]`, () => {
+ it('should return null if no config found', async () => {
+ const config = await getMethod(resolveConfigFile, mode)('/tmp')
+ expect(config).toBe(null)
+ })
- describe('#loadConfig', () => {
- it('should use default config without state.filePath', async () => {
- const config = await loadConfig({ dimensions: false })
- expect(config).toMatchInlineSnapshot(`
-Object {
- "dimensions": false,
- "expandProps": "end",
- "h2xConfig": null,
- "icon": false,
- "native": false,
- "prettier": true,
- "prettierConfig": null,
- "ref": false,
- "replaceAttrValues": null,
- "runtimeConfig": true,
- "svgProps": null,
- "svgo": true,
- "svgoConfig": null,
- "template": null,
- "titleProp": false,
-}
-`)
+ it('should return config path if found', async () => {
+ const config = await getMethod(resolveConfigFile, mode)(
+ path.join(__dirname, '__fixtures__/svgr'),
+ )
+ expect(config).toMatch(/__fixtures__(\/|\\)svgr(\/|\\)\.svgrrc$/)
+ })
})
- it('should load config using filePath', async () => {
- const config = await loadConfig(
- {},
- { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') },
- )
- expect(config).toMatchInlineSnapshot(`
-Object {
- "dimensions": true,
- "expandProps": "end",
- "h2xConfig": null,
- "icon": true,
- "native": false,
- "noSemi": true,
- "prettier": true,
- "prettierConfig": null,
- "ref": false,
- "replaceAttrValues": Array [
- Array [
- "#063855",
- "currentColor",
- ],
- ],
- "runtimeConfig": true,
- "svgProps": null,
- "svgo": true,
- "svgoConfig": null,
- "template": null,
- "titleProp": false,
-}
-`)
- })
+ describe(`#loadConfig [${mode}]`, () => {
+ it('should use default config without state.filePath', async () => {
+ const config = await getMethod(loadConfig, mode)({ dimensions: false })
+ expect(config).toMatchSnapshot()
+ })
- it('should not load config with "runtimeConfig: false', async () => {
- const config = await loadConfig(
- { useRuntimeConfig: false },
- { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') },
- )
- expect(config).toMatchInlineSnapshot(`
-Object {
- "dimensions": true,
- "expandProps": "end",
- "h2xConfig": null,
- "icon": true,
- "native": false,
- "noSemi": true,
- "prettier": true,
- "prettierConfig": null,
- "ref": false,
- "replaceAttrValues": Array [
- Array [
- "#063855",
- "currentColor",
- ],
- ],
- "runtimeConfig": true,
- "svgProps": null,
- "svgo": true,
- "svgoConfig": null,
- "template": null,
- "titleProp": false,
- "useRuntimeConfig": false,
-}
-`)
- })
+ it('should load config using filePath', async () => {
+ const config = await getMethod(loadConfig, mode)(
+ {},
+ { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') },
+ )
+ expect(config).toMatchSnapshot()
+ })
- it('should work with custom config path', async () => {
- const config = await loadConfig(
- { configFile: path.join(__dirname, '__fixtures__/svgr/.svgrrc') },
- { filePath: __dirname },
- )
- expect(config).toMatchInlineSnapshot(`
-Object {
- "dimensions": true,
- "expandProps": "end",
- "h2xConfig": null,
- "icon": true,
- "native": false,
- "noSemi": true,
- "prettier": true,
- "prettierConfig": null,
- "ref": false,
- "replaceAttrValues": Array [
- Array [
- "#063855",
- "currentColor",
- ],
- ],
- "runtimeConfig": true,
- "svgProps": null,
- "svgo": true,
- "svgoConfig": null,
- "template": null,
- "titleProp": false,
-}
-`)
+ it('should not load config with "runtimeConfig: false', async () => {
+ const config = await getMethod(loadConfig, mode)(
+ { useRuntimeConfig: false },
+ { filePath: path.join(__dirname, '__fixtures__/svgr/icon.svg') },
+ )
+ expect(config).toMatchSnapshot()
+ })
+
+ it('should work with custom config path', async () => {
+ const config = await getMethod(loadConfig, mode)(
+ { configFile: path.join(__dirname, '__fixtures__/svgr/.svgrrc') },
+ { filePath: __dirname },
+ )
+ expect(config).toMatchSnapshot()
+ })
})
})
})
diff --git a/packages/core/src/convert.js b/packages/core/src/convert.js
index 79b3cd8b..fa6d6b94 100644
--- a/packages/core/src/convert.js
+++ b/packages/core/src/convert.js
@@ -5,17 +5,26 @@ import transform from './plugins/transform'
import { expandState } from './util'
import { loadConfig } from './config'
-async function convert(code, baseConfig = {}, baseState = {}) {
- const state = expandState(baseState)
- const config = await loadConfig(baseConfig, baseState)
+function applyPlugins(code, config, state) {
+ state = expandState(state)
let result = code
// Remove null-byte character (copy/paste from Illustrator)
result = String(result).replace('\0', '')
- result = await svgo(result, config, state)
- result = await h2x(result, config, state)
- result = await transform(result, config, state)
- result = await prettier(result, config, state)
+ result = svgo(result, config, state)
+ result = h2x(result, config, state)
+ result = transform(result, config, state)
+ result = prettier(result, config, state)
return result
}
+async function convert(code, config = {}, state = {}) {
+ config = await loadConfig(config, state)
+ return applyPlugins(code, config, state)
+}
+
+convert.sync = (code, config = {}, state = {}) => {
+ config = loadConfig.sync(config, state)
+ return applyPlugins(code, config, state)
+}
+
export default convert
diff --git a/packages/core/src/convert.test.js b/packages/core/src/convert.test.js
index 8cc732c4..490e7c5c 100644
--- a/packages/core/src/convert.test.js
+++ b/packages/core/src/convert.test.js
@@ -22,6 +22,12 @@ describe('convert', () => {
expect(result).toMatchSnapshot()
})
+ it('should work synchronously', async () => {
+ const syncResult = convert.sync(svgBaseCode)
+ const asyncResult = await convert(svgBaseCode)
+ expect(syncResult).toEqual(asyncResult)
+ })
+
it('should remove style tags', async () => {
const result = await convert(
`
diff --git a/packages/core/src/plugins/__snapshots__/svgo.test.js.snap b/packages/core/src/plugins/__snapshots__/svgo.test.js.snap
index c419fd57..c9488274 100644
--- a/packages/core/src/plugins/__snapshots__/svgo.test.js.snap
+++ b/packages/core/src/plugins/__snapshots__/svgo.test.js.snap
@@ -1,5 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`svgo should not load runtime configuration with \`runtimeConfig: false\` 1`] = `""`;
+
exports[`svgo should not remove viewBox with icon option 1`] = `
"
`
describe('svgo', () => {
- it('should optimize svg', async () => {
- const result = await svgo(baseSvg, { svgo: true, runtimeConfig: true })
-
+ it('should optimize svg', () => {
+ const result = svgo(baseSvg, { svgo: true, runtimeConfig: true })
expect(result).toMatchSnapshot()
})
- it('should support config.svgoConfig', async () => {
- const result = await svgo(baseSvg, {
+ it('should support config.svgoConfig', () => {
+ const result = svgo(baseSvg, {
svgo: true,
runtimeConfig: true,
- svgoConfig: { plugins: [{ removeDesc: false }] },
+ svgoConfig: { svgos: [{ removeDesc: false }] },
})
expect(result).toMatchSnapshot()
})
- it('should support icon with config.svgoConfig plugins', async () => {
- const result = await svgo(baseSvg, {
+ it('should support icon with config.svgoConfig svgos', () => {
+ const result = svgo(baseSvg, {
svgo: true,
icon: true,
runtimeConfig: true,
- svgoConfig: { plugins: [{ removeDesc: false }] },
+ svgoConfig: { svgos: [{ removeDesc: false }] },
})
expect(result).toMatchSnapshot()
})
- it('should use state.filePath to detect configuration', async () => {
- const result = await svgo(
+ it('should use state.filePath to detect configuration', () => {
+ const result = svgo(
baseSvg,
{ svgo: true, runtimeConfig: true },
{ filePath: path.join(__dirname, '../__fixtures__/svgo') },
)
- // Desc should appear
- expect(result).toMatchInlineSnapshot(
- `"Created with Sketch."`,
- )
+ expect(result).toMatchSnapshot()
})
- it('should not load runtime configuration with `runtimeConfig: false`', async () => {
- const result = await svgo(
+ it('should not load runtime configuration with `runtimeConfig: false`', () => {
+ const result = svgo(
baseSvg,
{ svgo: true, runtimeConfig: false },
{ filePath: path.join(__dirname, '../__fixtures__/svgo') },
)
- // Desc should not appear
- expect(result).toMatchInlineSnapshot(
- `""`,
- )
+ expect(result).toMatchSnapshot()
})
- it('should not remove viewBox with icon option', async () => {
- const result = await svgo(
+ it('should not remove viewBox with icon option', () => {
+ const result = svgo(
baseSvg,
{ icon: true, runtimeConfig: true },
{ filePath: path.join(__dirname, '../__fixtures__/svgo') },