diff --git a/src/extractLoader.js b/src/extractLoader.js index c39d15a..c2d8bc9 100644 --- a/src/extractLoader.js +++ b/src/extractLoader.js @@ -75,6 +75,23 @@ function evalDependencyGraph({loaderContext, src, filename, publicPath = ""}) { } } + function extractQueryFromPath(givenRelativePath) { + const indexOfLastExclMark = givenRelativePath.lastIndexOf("!"); + const indexOfQuery = givenRelativePath.lastIndexOf("?"); + + if (indexOfQuery !== -1 && indexOfQuery > indexOfLastExclMark) { + return { + relativePathWithoutQuery: givenRelativePath.slice(0, indexOfQuery), + query: givenRelativePath.slice(indexOfQuery), + }; + } + + return { + relativePathWithoutQuery: givenRelativePath, + query: "", + }; + } + async function evalModule(src, filename) { const rndPlaceholder = "__EXTRACT_LOADER_PLACEHOLDER__" + rndNumber() + rndNumber(); const rndPlaceholderPattern = new RegExp(rndPlaceholder, "g"); @@ -91,10 +108,8 @@ function evalDependencyGraph({loaderContext, src, filename, publicPath = ""}) { exports, __webpack_public_path__: publicPath, // eslint-disable-line camelcase require: givenRelativePath => { - const indexOfQuery = Math.max(givenRelativePath.indexOf("?"), givenRelativePath.length); - const relativePathWithoutQuery = givenRelativePath.slice(0, indexOfQuery); + const {relativePathWithoutQuery, query} = extractQueryFromPath(givenRelativePath); const indexOfLastExclMark = relativePathWithoutQuery.lastIndexOf("!"); - const query = givenRelativePath.slice(indexOfQuery); const loaders = givenRelativePath.slice(0, indexOfLastExclMark + 1); const relativePath = relativePathWithoutQuery.slice(indexOfLastExclMark + 1); const absolutePath = resolve.sync(relativePath, { @@ -161,6 +176,9 @@ function rndNumber() { .slice(2); } +// getPublicPath() encapsulates the complexity of reading the publicPath from the current +// webpack config. Let's keep the complexity in this function. +/* eslint-disable complexity */ /** * Retrieves the public path from the loader options, context.options (webpack <4) or context._compilation (webpack 4+). * context._compilation is likely to get removed in a future release, so this whole function should be removed then. @@ -186,6 +204,7 @@ function getPublicPath(options, context) { return ""; } +/* eslint-enable complexity */ // For CommonJS interoperability module.exports = extractLoader; diff --git a/test/extractLoader.test.js b/test/extractLoader.test.js index a830b32..2e6cde3 100644 --- a/test/extractLoader.test.js +++ b/test/extractLoader.test.js @@ -21,6 +21,20 @@ describe("extractLoader", () => { expect(simpleJs).to.be.a.file(); expect(simpleJs).to.have.content("hello"); })); + it("should extract resource with query params into simple-css-with-query-param.js", () => + compile({testModule: "simple-css-with-query-params.js"}).then(() => { + const simpleJs = path.resolve(__dirname, "dist/simple-css-with-query-params-dist.js"); + + expect(simpleJs).to.be.a.file(); + expect(simpleJs).to.have.content("simple-dist.css"); + })); + it("should extract resource with query params and loader into simple-css-with-query-param-and-loader.js", () => + compile({testModule: "simple-css-with-query-params-and-loader.js"}).then(() => { + const simpleJs = path.resolve(__dirname, "dist/simple-css-with-query-params-and-loader-dist.js"); + + expect(simpleJs).to.be.a.file(); + expect(simpleJs).to.have.content("renamed-simple.css"); + })); it("should extract the html of modules/simple.html into simple.html", () => compile({testModule: "simple.html"}).then(() => { const simpleHtml = path.resolve(__dirname, "dist/simple-dist.html"); diff --git a/test/modules/simple-css-with-query-params-and-loader.js b/test/modules/simple-css-with-query-params-and-loader.js new file mode 100644 index 0000000..d651efb --- /dev/null +++ b/test/modules/simple-css-with-query-params-and-loader.js @@ -0,0 +1,2 @@ +/* eslint-disable import/unambiguous, import/no-unresolved, import/no-webpack-loader-syntax */ +module.exports = require("!!file-loader?name=renamed-simple.css!./simple.css?v=1.2"); diff --git a/test/modules/simple-css-with-query-params.js b/test/modules/simple-css-with-query-params.js new file mode 100644 index 0000000..82f99d9 --- /dev/null +++ b/test/modules/simple-css-with-query-params.js @@ -0,0 +1,2 @@ +/* eslint-disable import/unambiguous, import/no-unresolved */ +module.exports = require("./simple.css?v=1.2");