diff --git a/README.md b/README.md index 289bb32..bc74929 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,7 @@ The following tokens are replaced in the `name` parameter: * `[name]` the basename of the resource * `[path]` the path of the resource relative to the `context` query parameter or option. * `[folder]` the folder the resource is in. +* `[query]` the query parameters string without the leading `?` * `[emoji]` a random emoji representation of `options.content` * `[emoji:]` same as above, but with a customizable number of emojis * `[contenthash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md5 hash) @@ -212,6 +213,11 @@ loaderUtils.interpolateName(loaderContext, "html-[hash:6].html", { content: ... loaderUtils.interpolateName(loaderContext, "[hash]", { content: ... }); // => c31e9820c001c9c4a86bce33ce43b679 +// loaderContext.resourcePath = "/app/img/icon.svg" +// loaderContext.resourceQuery = "?color=red&bgColor=blue" +loaderUtils.interpolateName(loaderContext, "[name].[ext]?[query]", { content: ... }); +// => /app/img/icon.svg?color=red&bgColor=blue + // loaderContext.resourcePath = "/app/img/image.gif" loaderUtils.interpolateName(loaderContext, "[emoji]", { content: ... }); // => 👍 @@ -234,6 +240,11 @@ loaderUtils.interpolateName(loaderContext, "picture.png"); loaderUtils.interpolateName(loaderContext, "[path][name].[ext]?[hash]", { content: ... }); // => /app/dir/file.png?9473fdd0d880a43c21b7778d34872157 +// loaderContext.resourcePath = "/app/img/icon.png" +// loaderContext.resourceQuery = "?color=red&bgColor=blue" +loaderUtils.interpolateName(loaderContext, "[path][name].[ext]?[hash]&[query]", { content: ... }); +// => /app/img/icon.png?9473fdd0d880a43c21b7778d34872157&color=red&bgColor=blue + // loaderContext.resourcePath = "/app/js/page-home.js" loaderUtils.interpolateName(loaderContext, "script-[1].[ext]", { regExp: "page-(.*)\\.js", content: ... }); // => script-home.js diff --git a/lib/interpolateName.js b/lib/interpolateName.js index d1fa661..fe4696f 100644 --- a/lib/interpolateName.js +++ b/lib/interpolateName.js @@ -52,6 +52,11 @@ function interpolateName(loaderContext, name, options) { let basename = 'file'; let directory = ''; let folder = ''; + let query = ''; + if (loaderContext.resourceQuery) { + // If query was passed, strip the leading '?' character + query = loaderContext.resourceQuery.substr(1); + } if (loaderContext.resourcePath) { const parsed = path.parse(loaderContext.resourcePath); @@ -104,7 +109,8 @@ function interpolateName(loaderContext, name, options) { .replace(/\[ext\]/gi, () => ext) .replace(/\[name\]/gi, () => basename) .replace(/\[path\]/gi, () => directory) - .replace(/\[folder\]/gi, () => folder); + .replace(/\[folder\]/gi, () => folder) + .replace(/\[query\]/gi, () => query); if (regExp && loaderContext.resourcePath) { const match = loaderContext.resourcePath.match(new RegExp(regExp)); diff --git a/test/interpolateName.test.js b/test/interpolateName.test.js index e57443a..5d950a8 100644 --- a/test/interpolateName.test.js +++ b/test/interpolateName.test.js @@ -131,10 +131,31 @@ describe('interpolateName()', () => { 'test content', 'modal.[md5::base64:20].css', ], + [ + 'images/icon.svg?color=#ff0000&bgColor=#0000ff', + '[name].[ext]?[query]', + 'test content', + 'icon.svg?color=#ff0000&bgColor=#0000ff', + ], + [ + 'images/icon.svg?color=#ff0000&bgColor=#0000ff', + '[name].[ext]?[hash]&[query]', + 'test content', + 'icon.svg?9473fdd0d880a43c21b7778d34872157&color=#ff0000&bgColor=#0000ff', + ], ].forEach((test) => { it('should interpolate ' + test[0] + ' ' + test[1], () => { + const resourcePathParts = test[0].split('?'); + const resourcePath = resourcePathParts[0]; + const resourceQuery = resourcePathParts[1] + ? `?${resourcePathParts[1]}` + : undefined; + const interpolatedName = loaderUtils.interpolateName( - { resourcePath: test[0] }, + { + resourcePath, + resourceQuery, + }, test[1], { content: test[2] } );