From 4d3a703d01f2bff358520845a701fa18a1ea4be7 Mon Sep 17 00:00:00 2001 From: Erik Hughes Date: Thu, 19 Dec 2019 10:13:43 +0100 Subject: [PATCH 1/3] feat: extended options.paths to support functions --- README.md | 11 ++++++++++- lib/index.js | 10 ++++++++-- test/options.test.js | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 98333b6..1f7345c 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,16 @@ See [PostCSS] docs for examples for your environment. #### options.paths -Array of paths to resolve URL. Paths are tried in order, until an existing file is found. +Array of paths or function to resolve URL. Array paths are tried in order, until an existing file is found. +Function recieves `file`, `url`, and `opts` arguments and expects to return an absolute path as a `string`. + +For example + +```js +function paths(file, url, opts) { + return path.resolve('svgs', url); +} +``` Default: `false` - path will be relative to source file if it was specified. diff --git a/lib/index.js b/lib/index.js index 6932efa..80b99ce 100644 --- a/lib/index.js +++ b/lib/index.js @@ -44,7 +44,10 @@ module.exports = postcss.plugin( const { name, url } = parseRuleDefinition(node.params); const { params, selectors } = getRuleParams(node); const loader = { - id: resolveId(file, url, opts), + id: + typeof opts.paths === "function" + ? opts.paths(file, url, opts) + : resolveId(file, url, opts), parent: file, params, selectors, @@ -68,7 +71,10 @@ module.exports = postcss.plugin( statements.loaders.forEach( ({ url, params, valueNode, parsedValue }) => { const loader = { - id: resolveId(file, url, opts), + id: + typeof opts.paths === "function" + ? opts.paths(file, url, opts) + : resolveId(file, url, opts), parent: file, params, selectors: {}, diff --git a/test/options.test.js b/test/options.test.js index 97fa808..5480bdb 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -1,4 +1,5 @@ /* eslint-env mocha */ +const { resolve } = require("path"); const { compare } = require("./utils.js"); process.chdir(__dirname); @@ -33,6 +34,25 @@ test('should take file relatively to "paths" option', () => { ); }); +test('should resolve file using "paths" option as a function', () => { + return compare( + ` + @svg-load icon url(basic.svg) {} + background: svg-load('basic.svg'); + background: svg-inline(icon); + `, + ` + background: url("data:image/svg+xml;charset=utf-8,"); + background: url("data:image/svg+xml;charset=utf-8,"); + `, + { + from: "input.css", + paths: (file, url, opts) => resolve("fixtures", url), + encode: false + } + ); +}); + test('should find existing path from "paths" option', () => { return compare( ` From 0565c740d15a0d7bdab39c255710cd2c180f7fb1 Mon Sep 17 00:00:00 2001 From: Erik Hughes Date: Thu, 19 Dec 2019 10:22:50 +0100 Subject: [PATCH 2/3] feat: fallback to relative path if "paths" can't resolve --- lib/resolveId.js | 2 -- test/options.test.js | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/resolveId.js b/lib/resolveId.js index c50267b..5533869 100644 --- a/lib/resolveId.js +++ b/lib/resolveId.js @@ -12,8 +12,6 @@ module.exports = function resolveId(file, url, opts) { return absolutePath; } } - - return absolutePath; } if (file) { diff --git a/test/options.test.js b/test/options.test.js index 5480bdb..c1bfe19 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -91,6 +91,25 @@ test('should prefer "paths" option over "from"', () => { ); }); +test('should fallback to relative option if "paths" option can\'t be resolved', () => { + return compare( + ` + @svg-load icon url(fixtures/basic.svg) {} + background: svg-load('fixtures/basic.svg'); + background: svg-inline(icon); + `, + ` + background: url("data:image/svg+xml;charset=utf-8,"); + background: url("data:image/svg+xml;charset=utf-8,"); + `, + { + from: "input.css", + paths: ["./does_not_exist"], + encode: false + } + ); +}); + test("should ignore xmlns absence", () => { return compare( `background: svg-load('fixtures/basic.svg');`, From 962856e8eeb06c4bd7fda58aa6687abd910df846 Mon Sep 17 00:00:00 2001 From: Erik Hughes Date: Thu, 19 Dec 2019 10:36:10 +0100 Subject: [PATCH 3/3] refactor: migrated resolver to its own option --- README.md | 14 ++++++++++---- lib/index.js | 8 ++++---- test/options.test.js | 28 ++++++++++++++-------------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 1f7345c..71e7d29 100644 --- a/README.md +++ b/README.md @@ -53,18 +53,24 @@ See [PostCSS] docs for examples for your environment. #### options.paths -Array of paths or function to resolve URL. Array paths are tried in order, until an existing file is found. +Array of paths to resolve URL. Array paths are tried in order, until an existing file is found or will fallback to using the relative path. + +Default: `false` - path will be relative to source file if it was specified. + +#### options.resolve + +Function to resolve URL. This option will override the default file id resolver that uses "paths" option. Function recieves `file`, `url`, and `opts` arguments and expects to return an absolute path as a `string`. For example ```js -function paths(file, url, opts) { - return path.resolve('svgs', url); +function resolve(file, url, opts) { + return path.resolve('svg-folder', url); } ``` -Default: `false` - path will be relative to source file if it was specified. +Default: `function` - internal resolver using "paths" option and relative path. #### options.removeFill diff --git a/lib/index.js b/lib/index.js index 80b99ce..88d4b73 100644 --- a/lib/index.js +++ b/lib/index.js @@ -45,8 +45,8 @@ module.exports = postcss.plugin( const { params, selectors } = getRuleParams(node); const loader = { id: - typeof opts.paths === "function" - ? opts.paths(file, url, opts) + typeof opts.resolve === "function" + ? opts.resolve(file, url, opts) : resolveId(file, url, opts), parent: file, params, @@ -72,8 +72,8 @@ module.exports = postcss.plugin( ({ url, params, valueNode, parsedValue }) => { const loader = { id: - typeof opts.paths === "function" - ? opts.paths(file, url, opts) + typeof opts.resolve === "function" + ? opts.resolve(file, url, opts) : resolveId(file, url, opts), parent: file, params, diff --git a/test/options.test.js b/test/options.test.js index c1bfe19..d4eeccb 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -34,7 +34,7 @@ test('should take file relatively to "paths" option', () => { ); }); -test('should resolve file using "paths" option as a function', () => { +test('should find existing path from "paths" option', () => { return compare( ` @svg-load icon url(basic.svg) {} @@ -47,13 +47,13 @@ test('should resolve file using "paths" option as a function', () => { `, { from: "input.css", - paths: (file, url, opts) => resolve("fixtures", url), + paths: ["./does_not_exist", "./fixtures"], encode: false } ); }); -test('should find existing path from "paths" option', () => { +test('should prefer "paths" option over "from"', () => { return compare( ` @svg-load icon url(basic.svg) {} @@ -65,18 +65,18 @@ test('should find existing path from "paths" option', () => { background: url("data:image/svg+xml;charset=utf-8,"); `, { - from: "input.css", - paths: ["./does_not_exist", "./fixtures"], + from: "./fixtures/deeper/index.css", + paths: ["./fixtures"], encode: false } ); }); -test('should prefer "paths" option over "from"', () => { +test('should fallback to relative option if "paths" option can\'t be resolved', () => { return compare( ` - @svg-load icon url(basic.svg) {} - background: svg-load('basic.svg'); + @svg-load icon url(fixtures/basic.svg) {} + background: svg-load('fixtures/basic.svg'); background: svg-inline(icon); `, ` @@ -84,18 +84,18 @@ test('should prefer "paths" option over "from"', () => { background: url("data:image/svg+xml;charset=utf-8,"); `, { - from: "./fixtures/deeper/index.css", - paths: ["./fixtures"], + from: "input.css", + paths: ["./does_not_exist"], encode: false } ); }); -test('should fallback to relative option if "paths" option can\'t be resolved', () => { +test('should resolve file path using the "resolve" option function', () => { return compare( ` - @svg-load icon url(fixtures/basic.svg) {} - background: svg-load('fixtures/basic.svg'); + @svg-load icon url(basic.svg) {} + background: svg-load('basic.svg'); background: svg-inline(icon); `, ` @@ -104,7 +104,7 @@ test('should fallback to relative option if "paths" option can\'t be resolved', `, { from: "input.css", - paths: ["./does_not_exist"], + resolve: (file, url, opts) => resolve("fixtures", url), encode: false } );