diff --git a/README.md b/README.md index e1d0df64a..246716c31 100644 --- a/README.md +++ b/README.md @@ -60,17 +60,18 @@ See [below](#other-servers) for an example of use with fastify. ## Options -| Name | Type | Default | Description | -| :-----------------------------------------: | :-----------------------: | :-------------------------------------------: | :------------------------------------------------------------------------------------------------------------------- | -| **[`methods`](#methods)** | `Array` | `[ 'GET', 'HEAD' ]` | Allows to pass the list of HTTP request methods accepted by the middleware | -| **[`headers`](#headers)** | `Array\|Object\|Function` | `undefined` | Allows to pass custom HTTP headers on each request. | -| **[`index`](#index)** | `Boolean\|String` | `index.html` | If `false` (but not `undefined`), the server will not respond to requests to the root URL. | -| **[`mimeTypes`](#mimetypes)** | `Object` | `undefined` | Allows to register custom mime types or extension mappings. | -| **[`publicPath`](#publicpath)** | `String` | `output.publicPath` (from a configuration) | The public path that the middleware is bound to. | -| **[`stats`](#stats)** | `Boolean\|String\|Object` | `stats` (from a configuration) | Stats options object or preset name. | -| **[`serverSideRender`](#serversiderender)** | `Boolean` | `undefined` | Instructs the module to enable or disable the server-side rendering mode. | -| **[`writeToDisk`](#writetodisk)** | `Boolean\|Function` | `false` | Instructs the module to write files to the configured location on disk as specified in your `webpack` configuration. | -| **[`outputFileSystem`](#outputfilesystem)** | `Object` | [`memfs`](https://github.com/streamich/memfs) | Set the default file system which will be used by webpack as primary destination of generated files. | +| Name | Type | Default | Description | +| :-----------------------------------------: | :--------: | :-------------------------------------------: | :--------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| **[`methods`](#methods)** | `Array` | `[ 'GET', 'HEAD' ]` | Allows to pass the list of HTTP request methods accepted by the middleware | +| **[`headers`](#headers)** | `Array\ | Object\| Function` | `undefined` | Allows to pass custom HTTP headers on each request. | +| **[`index`](#index)** | `Boolean\ | String` | `index.html` | If `false` (but not `undefined`), the server will not respond to requests to the root URL. | +| **[`mimeTypes`](#mimetypes)** | `Object` | `undefined` | Allows to register custom mime types or extension mappings. | +| **[`mimeTypeDefault`](#mimetypedefault)** | `String` | `undefined` | Allows to register a default mime type when we can't determine the content type. | +| **[`publicPath`](#publicpath)** | `String` | `output.publicPath` (from a configuration) | The public path that the middleware is bound to. | +| **[`stats`](#stats)** | `Boolean\ | String\| Object` | `stats` (from a configuration) | Stats options object or preset name. | +| **[`serverSideRender`](#serversiderender)** | `Boolean` | `undefined` | Instructs the module to enable or disable the server-side rendering mode. | +| **[`writeToDisk`](#writetodisk)** | `Boolean\ | Function` | `false` | Instructs the module to write files to the configured location on disk as specified in your `webpack` configuration. | +| **[`outputFileSystem`](#outputfilesystem)** | `Object` | [`memfs`](https://github.com/streamich/memfs) | Set the default file system which will be used by webpack as primary destination of generated files. | The middleware accepts an `options` Object. The following is a property reference for the Object. @@ -164,6 +165,13 @@ eg. `mimeTypes: { phtml: 'text/html' }`. Please see the documentation for [`mime-types`](https://github.com/jshttp/mime-types) for more information. +### mimeTypeDefault + +Type: `String` +Default: `undefined` + +This property allows a user to register a default mime type when we can't determine the content type. + ### publicPath Type: `String` diff --git a/src/index.js b/src/index.js index 0d6d6dec0..7252768c0 100644 --- a/src/index.js +++ b/src/index.js @@ -80,6 +80,7 @@ const noop = () => {}; * @template {ServerResponse} ResponseInternal * @typedef {Object} Options * @property {{[key: string]: string}} [mimeTypes] + * @property {string | undefined} [mimeTypeDefault] * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk] * @property {string} [methods] * @property {Headers} [headers] diff --git a/src/middleware.js b/src/middleware.js index 0d314c43d..76c2e4eab 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -146,6 +146,12 @@ function wrapper(context) { // https://tools.ietf.org/html/rfc7231#section-3.1.1.5 if (contentType) { setHeaderForResponse(res, "Content-Type", contentType); + } else if (context.options.mimeTypeDefault) { + setHeaderForResponse( + res, + "Content-Type", + context.options.mimeTypeDefault + ); } } diff --git a/src/options.json b/src/options.json index 0fa043a38..7a56c491c 100644 --- a/src/options.json +++ b/src/options.json @@ -6,6 +6,11 @@ "link": "https://github.com/webpack/webpack-dev-middleware#mimetypes", "type": "object" }, + "mimeTypeDefault": { + "description": "Allows a user to register a default mime type when we can't determine the content type.", + "link": "https://github.com/webpack/webpack-dev-middleware#mimetypedefault", + "type": "string" + }, "writeToDisk": { "description": "Allows to write generated files on disk.", "link": "https://github.com/webpack/webpack-dev-middleware#writetodisk", diff --git a/test/middleware.test.js b/test/middleware.test.js index 4135765dd..da1bdf17a 100644 --- a/test/middleware.test.js +++ b/test/middleware.test.js @@ -2163,6 +2163,52 @@ describe.each([ }); }); + describe("mimeTypeDefault option", () => { + describe('should set the correct value for "Content-Type" header to unknown MIME type', () => { + beforeAll((done) => { + const outputPath = path.resolve(__dirname, "./outputs/basic"); + const compiler = getCompiler({ + ...webpackConfig, + output: { + filename: "bundle.js", + path: outputPath, + }, + }); + + instance = middleware(compiler, { + mimeTypeDefault: "text/plain", + }); + + app = framework(); + app.use(instance); + + listen = listenShorthand(done); + + req = request(app); + + instance.context.outputFileSystem.mkdirSync(outputPath, { + recursive: true, + }); + instance.context.outputFileSystem.writeFileSync( + path.resolve(outputPath, "file.unknown"), + "welcome" + ); + }); + + afterAll(close); + + it('should return the "200" code for the "GET" request to "file.html"', async () => { + const response = await req.get("/file.unknown"); + + expect(response.statusCode).toEqual(200); + expect( + response.headers["content-type"].startsWith("text/plain") + ).toBe(true); + expect(response.text).toEqual("welcome"); + }); + }); + }); + describe("watchOptions option", () => { describe("should work without value", () => { let compiler; diff --git a/types/index.d.ts b/types/index.d.ts index 152459637..e4e96841c 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -58,6 +58,7 @@ export = wdm; * @template {ServerResponse} ResponseInternal * @typedef {Object} Options * @property {{[key: string]: string}} [mimeTypes] + * @property {string | undefined} [mimeTypeDefault] * @property {boolean | ((targetPath: string) => boolean)} [writeToDisk] * @property {string} [methods] * @property {Headers} [headers] @@ -164,6 +165,7 @@ type Options< [key: string]: string; } | undefined; + mimeTypeDefault?: string | undefined; writeToDisk?: boolean | ((targetPath: string) => boolean) | undefined; methods?: string | undefined; headers?: Headers;