diff --git a/src/index.js b/src/index.js index 9e7cff79e..19b30a63b 100644 --- a/src/index.js +++ b/src/index.js @@ -90,6 +90,7 @@ const noop = () => {}; * @property {Watching | MultiWatching | undefined} watching watching * @property {Logger} logger logger * @property {OutputFileSystem} outputFileSystem output file system + * @property {boolean} isPlugin whether wdm is used as webpack plugin */ /** @@ -225,6 +226,7 @@ function wdm(compiler, options = {}) { options, compiler, logger: compiler.getInfrastructureLogger("webpack-dev-middleware"), + isPlugin: false, }; setupHooks(context); @@ -319,9 +321,10 @@ function wdm(compiler, options = {}) { /** * @template HapiServer * @template {HapiOptions} HapiOptionsInternal + * @param {boolean} usePlugin whether to use as webpack plugin * @returns {HapiPlugin} hapi wrapper */ -function hapiWrapper() { +function createHapiWrapper(usePlugin = false) { return { pkg: { name: "webpack-dev-middleware", @@ -337,6 +340,11 @@ function hapiWrapper() { const devMiddleware = wdm(compiler, rest); + if (usePlugin) { + // Use logger when used as webpack plugin + devMiddleware.context.isPlugin = true; + } + // @ts-expect-error if (!server.decorations.server.includes("webpackDevMiddleware")) { // @ts-expect-error @@ -387,18 +395,42 @@ function hapiWrapper() { }; } +/** + * @template HapiServer + * @template {HapiOptions} HapiOptionsInternal + * @returns {HapiPlugin} hapi wrapper + */ +function hapiWrapper() { + return createHapiWrapper(false); +} + +/** + * @template HapiServer + * @template {HapiOptions} HapiOptionsInternal + * @returns {HapiPlugin} hapi plugin wrapper + */ +function hapiPluginWrapper() { + return createHapiWrapper(true); +} + wdm.hapiWrapper = hapiWrapper; +wdm.hapiPluginWrapper = hapiPluginWrapper; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] * @param {Compiler | MultiCompiler} compiler compiler * @param {Options=} options options + * @param {boolean} usePlugin whether to use as webpack plugin * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} kow wrapper */ -function koaWrapper(compiler, options) { +function createKoaWrapper(compiler, options, usePlugin = false) { const devMiddleware = wdm(compiler, options); + if (usePlugin) { + devMiddleware.context.isPlugin = true; + } + /** * @param {{ req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse, status: number, body: string | Buffer | import("fs").ReadStream | { message: string }, state: object }} ctx context * @param {EXPECTED_FUNCTION} next next @@ -508,18 +540,46 @@ function koaWrapper(compiler, options) { return webpackDevMiddleware; } +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} kow wrapper + */ +function koaWrapper(compiler, options) { + return createKoaWrapper(compiler, options, false); +} + +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} kow plugin wrapper + */ +function koaPluginWrapper(compiler, options) { + return createKoaWrapper(compiler, options, true); +} + wdm.koaWrapper = koaWrapper; +wdm.koaPluginWrapper = koaPluginWrapper; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] * @param {Compiler | MultiCompiler} compiler compiler * @param {Options=} options options + * @param {boolean} usePlugin whether to use as webpack plugin * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} hono wrapper */ -function honoWrapper(compiler, options) { +function createHonoWrapper(compiler, options, usePlugin = false) { const devMiddleware = wdm(compiler, options); + if (usePlugin) { + devMiddleware.context.isPlugin = true; + } + /** * @param {{ env: EXPECTED_ANY, body: EXPECTED_ANY, json: EXPECTED_ANY, status: EXPECTED_ANY, set: EXPECTED_ANY, req: RequestInternal & import("./utils/compatibleAPI").ExpectedIncomingMessage & { header: (name: string) => string }, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse & { headers: EXPECTED_ANY, status: EXPECTED_ANY } }} context context * @param {EXPECTED_FUNCTION} next next function @@ -685,6 +745,45 @@ function honoWrapper(compiler, options) { return webpackDevMiddleware; } +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} hono wrapper + */ +function honoWrapper(compiler, options) { + return createHonoWrapper(compiler, options, false); +} + +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} hono plugin wrapper + */ +function honoPluginWrapper(compiler, options) { + return createHonoWrapper(compiler, options, true); +} + wdm.honoWrapper = honoWrapper; +wdm.honoPluginWrapper = honoPluginWrapper; + +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {API} webpack dev middleware + */ +function plugin(compiler, options = {}) { + const instance = wdm(compiler, options); + // Mark that wdm is used as webpack plugin (to use logger instead of console.log) + instance.context.isPlugin = true; + return instance; +} + +wdm.plugin = plugin; module.exports = wdm; diff --git a/src/utils/setupHooks.js b/src/utils/setupHooks.js index 50c55a0f8..abd88205c 100644 --- a/src/utils/setupHooks.js +++ b/src/utils/setupHooks.js @@ -138,8 +138,13 @@ function setupHooks(context) { // Avoid extra empty line when `stats: 'none'` if (printedStats) { - // eslint-disable-next-line no-console - console.log(printedStats); + if (context.isPlugin) { + // Use logger when used as webpack plugin + logger.log(printedStats); + } else { + // eslint-disable-next-line no-console + console.log(printedStats); + } } context.callbacks = []; diff --git a/types/index.d.ts b/types/index.d.ts index e3fb18505..d5cb9e54c 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -165,8 +165,12 @@ declare function wdm< declare namespace wdm { export { hapiWrapper, + hapiPluginWrapper, koaWrapper, + koaPluginWrapper, honoWrapper, + honoPluginWrapper, + plugin, Schema, Compiler, MultiCompiler, @@ -231,6 +235,15 @@ declare function hapiWrapper< HapiServer, HapiOptionsInternal extends HapiOptions, >(): HapiPlugin; +/** + * @template HapiServer + * @template {HapiOptions} HapiOptionsInternal + * @returns {HapiPlugin} hapi plugin wrapper + */ +declare function hapiPluginWrapper< + HapiServer, + HapiOptionsInternal extends HapiOptions, +>(): HapiPlugin; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] @@ -245,6 +258,20 @@ declare function koaWrapper< compiler: Compiler | MultiCompiler, options?: Options | undefined, ): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void; +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} kow plugin wrapper + */ +declare function koaPluginWrapper< + RequestInternal extends IncomingMessage = import("http").IncomingMessage, + ResponseInternal extends ServerResponse = ServerResponse, +>( + compiler: Compiler | MultiCompiler, + options?: Options | undefined, +): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void; /** * @template {IncomingMessage} [RequestInternal=IncomingMessage] * @template {ServerResponse} [ResponseInternal=ServerResponse] @@ -259,6 +286,34 @@ declare function honoWrapper< compiler: Compiler | MultiCompiler, options?: Options | undefined, ): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void; +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void} hono plugin wrapper + */ +declare function honoPluginWrapper< + RequestInternal extends IncomingMessage = import("http").IncomingMessage, + ResponseInternal extends ServerResponse = ServerResponse, +>( + compiler: Compiler | MultiCompiler, + options?: Options | undefined, +): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise | void; +/** + * @template {IncomingMessage} [RequestInternal=IncomingMessage] + * @template {ServerResponse} [ResponseInternal=ServerResponse] + * @param {Compiler | MultiCompiler} compiler compiler + * @param {Options=} options options + * @returns {API} webpack dev middleware + */ +declare function plugin< + RequestInternal extends IncomingMessage = import("http").IncomingMessage, + ResponseInternal extends ServerResponse = ServerResponse, +>( + compiler: Compiler | MultiCompiler, + options?: Options | undefined, +): API; type Schema = import("schema-utils/declarations/validate").Schema; type Compiler = import("webpack").Compiler; type MultiCompiler = import("webpack").MultiCompiler;