From 906719a952eb705bcb87ad5e40b72be315e41a05 Mon Sep 17 00:00:00 2001 From: Jonas Pommerening Date: Tue, 15 Nov 2016 08:36:48 +0100 Subject: [PATCH 1/3] (feature) add publicPath query option --- package.json | 3 +++ src/extractLoader.js | 5 ++++- test/extractLoader.test.js | 13 ++++++++++++- test/support/compile.js | 8 ++++---- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 77d6206..fa03d68 100644 --- a/package.json +++ b/package.json @@ -44,5 +44,8 @@ "rimraf": "^2.5.1", "style-loader": "^0.13.0", "webpack": "^1.12.13" + }, + "dependencies": { + "loader-utils": "^0.2.16" } } diff --git a/src/extractLoader.js b/src/extractLoader.js index 55f33db..fa22db2 100644 --- a/src/extractLoader.js +++ b/src/extractLoader.js @@ -1,5 +1,6 @@ import vm from "vm"; import path from "path"; +import { parseQuery } from "loader-utils"; /** * @name LoaderContext @@ -26,6 +27,8 @@ const rndPlaceholder = "__EXTRACT_LOADER_PLACEHOLDER__" + rndNumber() + rndNumbe */ function extractLoader(content) { const callback = this.async(); + const query = parseQuery(this.query); + const publicPath = typeof query.publicPath !== "undefined" ? query.publicPath : this.options.output.publicPath; const dependencies = []; const script = new vm.Script(content, { filename: this.resourcePath, @@ -60,7 +63,7 @@ function extractLoader(content) { Promise.all(dependencies.map(loadModule, this)) .then(sources => sources.map( // runModule may throw an error, so it's important that our promise is rejected in this case - (src, i) => runModule(src, dependencies[i], this.options.output.publicPath) + (src, i) => runModule(src, dependencies[i], publicPath) )) .then(results => sandbox.module.exports.toString() .replace(new RegExp(rndPlaceholder, "g"), () => results.shift()) diff --git a/test/extractLoader.test.js b/test/extractLoader.test.js index 51da537..1f4b566 100644 --- a/test/extractLoader.test.js +++ b/test/extractLoader.test.js @@ -109,6 +109,16 @@ describe("extractLoader", () => { expect(imgHtml).to.have.content.that.match(//); }) ); + it("should override the configured publicPath with the publicPath query option", () => + compile({ testModule: "img.html", publicPath: "/test/", query: "?publicPath=/other/" }).then(() => { + const imgHtml = path.resolve(__dirname, "dist/img-dist.html"); + const imgJpg = path.resolve(__dirname, "dist/hi-dist.jpg"); + + expect(imgHtml).to.be.a.file(); + expect(imgJpg).to.be.a.file(); + expect(imgHtml).to.have.content.that.match(//); + }) + ); it("should report syntax errors", () => compile({ testModule: "error.js" }).then( () => { throw new Error("Did not throw expected error"); }, @@ -127,7 +137,8 @@ describe("extractLoader", () => { }, cacheable() { cacheableCalled = true; - } + }, + options: { output: {} } }; let cacheableCalled = false; diff --git a/test/support/compile.js b/test/support/compile.js index 351dd2e..50523e8 100644 --- a/test/support/compile.js +++ b/test/support/compile.js @@ -1,7 +1,7 @@ import webpack from "webpack"; import path from "path"; -export default function ({ testModule, publicPath }) { +export default function ({ testModule, publicPath, query = "" }) { const testModulePath = path.resolve(__dirname, "../modules/", testModule); return new Promise((resolve, reject) => { @@ -20,14 +20,14 @@ export default function ({ testModule, publicPath }) { loaders: [ // appending -dist so we can check if url rewriting is working "file?name=[name]-dist.[ext]", - path.resolve(__dirname, "../../lib/extractLoader.js") + path.resolve(__dirname, "../../lib/extractLoader.js") + query ] }, { test: /\.html$/, loaders: [ "file?name=[name]-dist.[ext]", - path.resolve(__dirname, "../../lib/extractLoader.js"), + path.resolve(__dirname, "../../lib/extractLoader.js") + query, "html?" + JSON.stringify({ attrs: ["img:src", "link:href"] }) @@ -37,7 +37,7 @@ export default function ({ testModule, publicPath }) { test: /\.css$/, loaders: [ "file?name=[name]-dist.[ext]", - path.resolve(__dirname, "../../lib/extractLoader.js"), + path.resolve(__dirname, "../../lib/extractLoader.js") + query, "css" ] }, From 18219c33492168cb05d0228c96281d12bb71478a Mon Sep 17 00:00:00 2001 From: Jonas Pommerening Date: Thu, 17 Nov 2016 16:17:47 +0100 Subject: [PATCH 2/3] Add documentation for publicPath option --- README.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 362d739..cf16c04 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,34 @@ into Options ------------------------------------------------------------------------ -The are currently no options.
-You need one? Then you should think about: +There is currently exactly one option: `publicPath`. +If you are using a relative `publicPath` in webpack's [output options]() and extracting to a file with the `file-loader`, you might need this to account for the location of your extracted file. + +Example: +```js +module.exports = { + output: { + path: path.resolve( './dist' ), + publicPath: 'dist/' + }, + module: { + loaders: [ + { + test: /\.css$/, + loaders: [ + // target file: dist/assets/file.css + "file?name=assets/[name].[ext]", + // back up one directory to reach "dist/" + "extract?publicPath=../", + "css" + ] + } + ] + } +}; +``` + +You need another option? Then you should think about:
From 3d0cf2bc927f71c7918d1fe1f6404c7ce2e538e9 Mon Sep 17 00:00:00 2001 From: Jonas Pommerening Date: Thu, 17 Nov 2016 16:19:37 +0100 Subject: [PATCH 3/3] Add missing link to webpack documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf16c04..a2bea3b 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ Options ------------------------------------------------------------------------ There is currently exactly one option: `publicPath`. -If you are using a relative `publicPath` in webpack's [output options]() and extracting to a file with the `file-loader`, you might need this to account for the location of your extracted file. +If you are using a relative `publicPath` in webpack's [output options](http://webpack.github.io/docs/configuration.html#output-publicpath) and extracting to a file with the `file-loader`, you might need this to account for the location of your extracted file. Example: ```js