diff --git a/lib/Server.js b/lib/Server.js index 44584dd3c7..2ce4c52725 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1983,7 +1983,39 @@ class Server { const _path = req.path; try { - const filename = this.middleware.getFilenameFromUrl(`${_path}.js`); + let filename; + let extension; + let scriptType; + + // _path = "/main" -> outputFilename = "main" + // _path = "/main.other" -> outputFilename = "main.other" + const outputFilename = _path.slice(1); + + let isOutputModule = false; + + const stats = this.stats.stats ? this.stats.stats : [this.stats]; + + for (const item of stats) { + for (const [key, value] of item.compilation.assetsInfo) { + const assetExtension = path.extname(key); + const assetBasename = path.basename(key, assetExtension); + + if (assetBasename === outputFilename) { + extension = assetExtension; + isOutputModule = value.javascriptModule; + } + } + } + + if (isOutputModule) { + filename = this.middleware.getFilenameFromUrl(`${_path}${extension}`); + scriptType = "module"; + } else { + extension = ".js"; + filename = this.middleware.getFilenameFromUrl(`${_path}${extension}`); + scriptType = "text/javascript"; + } + const isFile = this.middleware.context.outputFileSystem .statSync(filename) .isFile(); @@ -1994,7 +2026,7 @@ class Server { // Serve a page that executes the javascript const queries = req._parsedUrl.search || ""; - const responsePage = ``; + const responsePage = ``; res.send(responsePage); } catch (error) { diff --git a/test/e2e/__snapshots__/magic-html.test.js.snap.webpack4 b/test/e2e/__snapshots__/magic-html.test.js.snap.webpack4 index 287d0b3c4a..80239b28d4 100644 --- a/test/e2e/__snapshots__/magic-html.test.js.snap.webpack4 +++ b/test/e2e/__snapshots__/magic-html.test.js.snap.webpack4 @@ -1,30 +1,192 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`magicHtml option disabled should not handle GET request to magic async html: console messages 1`] = ` +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): console messages 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", ] `; -exports[`magicHtml option disabled should not handle GET request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; -exports[`magicHtml option disabled should not handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option disabled should not handle GET request to magic async html: response status 1`] = `404`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response status 1`] = `404`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: console messages 1`] = ` +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle.other
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", ] `; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: response status 1`] = `404`; +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; -exports[`magicHtml option enabled should handle GET request to magic async html: console messages 1`] = ` +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): console messages 1`] = ` Array [ "[HMR] Waiting for update signal from WDS...", "Hey.", @@ -33,16 +195,20 @@ Array [ ] `; -exports[`magicHtml option enabled should handle GET request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response status 1`] = `200`; -exports[`magicHtml option enabled should handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response text 1`] = `""`; -exports[`magicHtml option enabled should handle GET request to magic async html: response status 1`] = `200`; +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): console messages 1`] = `Array []`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: console messages 1`] = `Array []`; +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): page errors 1`] = `Array []`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response status 1`] = `200`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: response status 1`] = `200`; +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response text 1`] = `""`; diff --git a/test/e2e/__snapshots__/magic-html.test.js.snap.webpack5 b/test/e2e/__snapshots__/magic-html.test.js.snap.webpack5 index 287d0b3c4a..01c7133ac0 100644 --- a/test/e2e/__snapshots__/magic-html.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/magic-html.test.js.snap.webpack5 @@ -1,30 +1,112 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`magicHtml option disabled should not handle GET request to magic async html: console messages 1`] = ` +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): console messages 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", ] `; -exports[`magicHtml option disabled should not handle GET request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; -exports[`magicHtml option disabled should not handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option disabled should not handle GET request to magic async html: response status 1`] = `404`; +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response status 1`] = `404`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: console messages 1`] = ` +exports[`magicHtml option disabled filename bundle.js should not handle GET request to magic async html (/bundle): response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.js should not handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): console messages 1`] = ` Array [ "Failed to load resource: the server responded with a status of 404 (Not Found)", ] `; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option disabled should not handle HEAD request to magic async html: response status 1`] = `404`; +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response status 1`] = `404`; -exports[`magicHtml option enabled should handle GET request to magic async html: console messages 1`] = ` +exports[`magicHtml option disabled filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle.other
+ + +" +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response status 1`] = `404`; + +exports[`magicHtml option disabled filename bundle.other.js should not handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): console messages 1`] = ` Array [ "[HMR] Waiting for update signal from WDS...", "Hey.", @@ -33,16 +115,341 @@ Array [ ] `; -exports[`magicHtml option enabled should handle GET request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.js should handle GET request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.js should handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.other.js should handle GET request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; + +exports[`magicHtml option enabled filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response status 1`] = `200`; + +exports[`magicHtml option enabled multi compiler mode should handle GET request to magic async html (/main): response text 1`] = `""`; + +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response status 1`] = `200`; + +exports[`magicHtml option enabled multi compiler mode should handle HEAD request to magic async html (/main): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle GET request to magic async html (/bundle): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle GET request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle GET request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle HEAD request to magic async html (/bundle): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle HEAD request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.js should not handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: false filename bundle.other.js should not handle GET request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle GET request to magic async html (/bundle): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle GET request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle GET request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle HEAD request to magic async html (/bundle): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle HEAD request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.js should handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle GET request to magic async html (/bundle.other): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle GET request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle GET request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle GET request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle GET request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should handle HEAD request to magic async html (/bundle.other): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should not handle GET request to /bundle: console messages 1`] = ` +Array [ + "Failed to load resource: the server responded with a status of 404 (Not Found)", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should not handle GET request to /bundle: page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should not handle GET request to /bundle: response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should not handle GET request to /bundle: response status 1`] = `404`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension filename bundle.other.js should not handle GET request to /bundle: response text 1`] = ` +" + + + +Error + + +
Cannot GET /bundle
+ + +" +`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle GET request to magic async html (/bundle): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle GET request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle GET request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle GET request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle GET request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle HEAD request to magic async html (/bundle): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle HEAD request to magic async html (/bundle): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle HEAD request to magic async html (/bundle): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle HEAD request to magic async html (/bundle): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true and .js extension multi compiler mode should handle HEAD request to magic async html (/bundle): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle GET request to magic async html (/main): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle GET request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle GET request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle GET request to magic async html (/main): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle GET request to magic async html (/main): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle HEAD request to magic async html (/main): console messages 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle HEAD request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle HEAD request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle HEAD request to magic async html (/main): response status 1`] = `200`; + +exports[`magicHtml option enabled with experiments.outputModule: true in multi compiler mode should handle HEAD request to magic async html (/main): response text 1`] = `""`; + +exports[`magicHtml option enabled with experiments.outputModule: true should handle GET request to magic async html (/main): console messages 1`] = ` +Array [ + "[HMR] Waiting for update signal from WDS...", + "Hey.", + "[webpack-dev-server] Hot Module Replacement enabled.", + "[webpack-dev-server] Live Reloading enabled.", +] +`; + +exports[`magicHtml option enabled with experiments.outputModule: true should handle GET request to magic async html (/main): page errors 1`] = `Array []`; + +exports[`magicHtml option enabled with experiments.outputModule: true should handle GET request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; + +exports[`magicHtml option enabled with experiments.outputModule: true should handle GET request to magic async html (/main): response status 1`] = `200`; -exports[`magicHtml option enabled should handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle GET request to magic async html (/main): response text 1`] = `""`; -exports[`magicHtml option enabled should handle GET request to magic async html: response status 1`] = `200`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle HEAD request to magic async html (/main): console messages 1`] = `Array []`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: console messages 1`] = `Array []`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle HEAD request to magic async html (/main): page errors 1`] = `Array []`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: page errors 1`] = `Array []`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle HEAD request to magic async html (/main): response headers content-type 1`] = `"text/html; charset=utf-8"`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle HEAD request to magic async html (/main): response status 1`] = `200`; -exports[`magicHtml option enabled should handle HEAD request to magic async html: response status 1`] = `200`; +exports[`magicHtml option enabled with experiments.outputModule: true should handle HEAD request to magic async html (/main): response text 1`] = `""`; diff --git a/test/e2e/magic-html.test.js b/test/e2e/magic-html.test.js index 90e72315f4..dd1e4c9a47 100644 --- a/test/e2e/magic-html.test.js +++ b/test/e2e/magic-html.test.js @@ -3,9 +3,13 @@ const webpack = require("webpack"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); +const multiCompilerConfig = require("../fixtures/multi-compiler-one-configuration/webpack.config"); const runBrowser = require("../helpers/run-browser"); +const isWebpack5 = require("../helpers/isWebpack5"); const port = require("../ports-map")["magic-html-option"]; +const webpack5Test = isWebpack5 ? describe : describe.skip; + describe("magicHtml option", () => { describe("enabled", () => { let compiler; @@ -15,8 +19,308 @@ describe("magicHtml option", () => { let pageErrors; let consoleMessages; + describe("filename bundle.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.js", + }, + }); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/bundle)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("filename bundle.other.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.other.js", + }, + }); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/bundle.other)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle GET request to /bundle", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle.other)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("multi compiler mode", () => { + beforeEach(async () => { + compiler = webpack(multiCompilerConfig); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/main)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/main`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/main)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/main`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + }); + + webpack5Test("enabled with experiments.outputModule: true", () => { + let compiler; + let server; + let page; + let browser; + let pageErrors; + let consoleMessages; + beforeEach(async () => { - compiler = webpack(config); + compiler = webpack({ + ...config, + experiments: { + outputModule: true, + }, + }); server = new Server({ port, magicHtml: true }, compiler); await server.start(); @@ -32,7 +336,7 @@ describe("magicHtml option", () => { await server.stop(); }); - it("should handle GET request to magic async html", async () => { + it("should handle GET request to magic async html (/main)", async () => { page .on("console", (message) => { consoleMessages.push(message); @@ -51,6 +355,8 @@ describe("magicHtml option", () => { expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages" ); @@ -58,7 +364,7 @@ describe("magicHtml option", () => { expect(pageErrors).toMatchSnapshot("page errors"); }); - it("should handle HEAD request to magic async html", async () => { + it("should handle HEAD request to magic async html (/main)", async () => { await page.setRequestInterception(true); page @@ -82,6 +388,8 @@ describe("magicHtml option", () => { expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( "console messages" ); @@ -90,7 +398,420 @@ describe("magicHtml option", () => { }); }); - describe("disabled", () => { + webpack5Test( + "enabled with experiments.outputModule: true in multi compiler mode", + () => { + let compiler; + let server; + let page; + let browser; + let pageErrors; + let consoleMessages; + + beforeEach(async () => { + compiler = webpack([ + { + ...multiCompilerConfig[0], + experiments: { + outputModule: true, + }, + }, + ]); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/main)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/main`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/main)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/main`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + } + ); + + webpack5Test( + "enabled with experiments.outputModule: true and .js extension", + () => { + let compiler; + let server; + let page; + let browser; + let pageErrors; + let consoleMessages; + + describe("filename bundle.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.js", + }, + experiments: { + outputModule: true, + }, + }); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/bundle)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("filename bundle.other.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.other.js", + }, + experiments: { + outputModule: true, + }, + }); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/bundle.other)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle GET request to /bundle", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle.other)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + + describe("multi compiler mode", () => { + beforeEach(async () => { + compiler = webpack([ + { + ...multiCompilerConfig[0], + output: { + path: "/", + filename: "bundle.js", + }, + experiments: { + outputModule: true, + }, + }, + config, + ]); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should handle GET request to magic async html (/bundle)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + }); + } + ); + + webpack5Test("enabled with experiments.outputModule: false", () => { let compiler; let server; let page; @@ -98,78 +819,431 @@ describe("magicHtml option", () => { let pageErrors; let consoleMessages; - beforeEach(async () => { - compiler = webpack(config); - server = new Server({ port, magicHtml: false }, compiler); + describe("filename bundle.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.js", + }, + experiments: { + outputModule: false, + }, + }); + server = new Server({ port, magicHtml: true }, compiler); - await server.start(); + await server.start(); - ({ page, browser } = await runBrowser()); + ({ page, browser } = await runBrowser()); - pageErrors = []; - consoleMessages = []; + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should not handle GET request to magic async html (/bundle)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle HEAD request to magic async html (/bundle)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); }); - afterEach(async () => { - await browser.close(); - await server.stop(); + describe("filename bundle.other.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.other.js", + }, + experiments: { + outputModule: false, + }, + }); + server = new Server({ port, magicHtml: true }, compiler); + + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should not handle GET request to magic async html (/bundle.other)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle GET request to /bundle", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should handle HEAD request to magic async html (/bundle.other)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); }); + }); - it("should not handle GET request to magic async html", async () => { - page - .on("console", (message) => { - consoleMessages.push(message); - }) - .on("pageerror", (error) => { - pageErrors.push(error); + describe("disabled", () => { + let compiler; + let server; + let page; + let browser; + let pageErrors; + let consoleMessages; + + describe("filename bundle.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.js", + }, }); + server = new Server({ port, magicHtml: false }, compiler); - const response = await page.goto(`http://127.0.0.1:${port}/main`, { - waitUntil: "networkidle0", + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; }); - expect(response.headers()["content-type"]).toMatchSnapshot( - "response headers content-type" - ); + afterEach(async () => { + await browser.close(); + await server.stop(); + }); - expect(response.status()).toMatchSnapshot("response status"); + it("should not handle GET request to magic async html (/bundle)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); - expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( - "console messages" - ); + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); - expect(pageErrors).toMatchSnapshot("page errors"); + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle HEAD request to magic async html (/bundle)", async () => { + await page.setRequestInterception(true); + + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", + }); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); }); - it("should not handle HEAD request to magic async html", async () => { - await page.setRequestInterception(true); + describe("filename bundle.other.js", () => { + beforeEach(async () => { + compiler = webpack({ + ...config, + output: { + path: "/", + filename: "bundle.other.js", + }, + }); + server = new Server({ port, magicHtml: false }, compiler); - page - .on("console", (message) => { - consoleMessages.push(message); - }) - .on("pageerror", (error) => { - pageErrors.push(error); - }) - .on("request", (interceptedRequest) => { - interceptedRequest.continue({ method: "HEAD" }); + await server.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); + + afterEach(async () => { + await browser.close(); + await server.stop(); + }); + + it("should not handle GET request to magic async html (/bundle.other)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); + + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); + + it("should not handle GET request to /bundle", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); + + const response = await page.goto(`http://127.0.0.1:${port}/bundle`, { + waitUntil: "networkidle0", }); - const response = await page.goto(`http://127.0.0.1:${port}/main`, { - waitUntil: "networkidle0", + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); }); - expect(response.headers()["content-type"]).toMatchSnapshot( - "response headers content-type" - ); + it("should not handle HEAD request to magic async html (/bundle.other)", async () => { + await page.setRequestInterception(true); - expect(response.status()).toMatchSnapshot("response status"); + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }) + .on("request", (interceptedRequest) => { + interceptedRequest.continue({ method: "HEAD" }); + }); - expect(consoleMessages.map((message) => message.text())).toMatchSnapshot( - "console messages" - ); + const response = await page.goto( + `http://127.0.0.1:${port}/bundle.other`, + { + waitUntil: "networkidle0", + } + ); - expect(pageErrors).toMatchSnapshot("page errors"); + expect(response.headers()["content-type"]).toMatchSnapshot( + "response headers content-type" + ); + + expect(response.status()).toMatchSnapshot("response status"); + + expect(await response.text()).toMatchSnapshot("response text"); + + expect( + consoleMessages.map((message) => message.text()) + ).toMatchSnapshot("console messages"); + + expect(pageErrors).toMatchSnapshot("page errors"); + }); }); }); });