Skip to content

Commit 65c1005

Browse files
authored
feat: add support for plugin usage with dedicated wrappers and logging
1 parent df7ddb4 commit 65c1005

3 files changed

Lines changed: 164 additions & 5 deletions

File tree

src/index.js

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ const noop = () => {};
9090
* @property {Watching | MultiWatching | undefined} watching watching
9191
* @property {Logger} logger logger
9292
* @property {OutputFileSystem} outputFileSystem output file system
93+
* @property {boolean} isPlugin whether wdm is used as webpack plugin
9394
*/
9495

9596
/**
@@ -225,6 +226,7 @@ function wdm(compiler, options = {}) {
225226
options,
226227
compiler,
227228
logger: compiler.getInfrastructureLogger("webpack-dev-middleware"),
229+
isPlugin: false,
228230
};
229231

230232
setupHooks(context);
@@ -319,9 +321,10 @@ function wdm(compiler, options = {}) {
319321
/**
320322
* @template HapiServer
321323
* @template {HapiOptions} HapiOptionsInternal
324+
* @param {boolean} usePlugin whether to use as webpack plugin
322325
* @returns {HapiPlugin<HapiServer, HapiOptionsInternal>} hapi wrapper
323326
*/
324-
function hapiWrapper() {
327+
function createHapiWrapper(usePlugin = false) {
325328
return {
326329
pkg: {
327330
name: "webpack-dev-middleware",
@@ -337,6 +340,11 @@ function hapiWrapper() {
337340

338341
const devMiddleware = wdm(compiler, rest);
339342

343+
if (usePlugin) {
344+
// Use logger when used as webpack plugin
345+
devMiddleware.context.isPlugin = true;
346+
}
347+
340348
// @ts-expect-error
341349
if (!server.decorations.server.includes("webpackDevMiddleware")) {
342350
// @ts-expect-error
@@ -387,18 +395,42 @@ function hapiWrapper() {
387395
};
388396
}
389397

398+
/**
399+
* @template HapiServer
400+
* @template {HapiOptions} HapiOptionsInternal
401+
* @returns {HapiPlugin<HapiServer, HapiOptionsInternal>} hapi wrapper
402+
*/
403+
function hapiWrapper() {
404+
return createHapiWrapper(false);
405+
}
406+
407+
/**
408+
* @template HapiServer
409+
* @template {HapiOptions} HapiOptionsInternal
410+
* @returns {HapiPlugin<HapiServer, HapiOptionsInternal>} hapi plugin wrapper
411+
*/
412+
function hapiPluginWrapper() {
413+
return createHapiWrapper(true);
414+
}
415+
390416
wdm.hapiWrapper = hapiWrapper;
417+
wdm.hapiPluginWrapper = hapiPluginWrapper;
391418

392419
/**
393420
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
394421
* @template {ServerResponse} [ResponseInternal=ServerResponse]
395422
* @param {Compiler | MultiCompiler} compiler compiler
396423
* @param {Options<RequestInternal, ResponseInternal>=} options options
424+
* @param {boolean} usePlugin whether to use as webpack plugin
397425
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} kow wrapper
398426
*/
399-
function koaWrapper(compiler, options) {
427+
function createKoaWrapper(compiler, options, usePlugin = false) {
400428
const devMiddleware = wdm(compiler, options);
401429

430+
if (usePlugin) {
431+
devMiddleware.context.isPlugin = true;
432+
}
433+
402434
/**
403435
* @param {{ req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse, status: number, body: string | Buffer | import("fs").ReadStream | { message: string }, state: object }} ctx context
404436
* @param {EXPECTED_FUNCTION} next next
@@ -508,18 +540,46 @@ function koaWrapper(compiler, options) {
508540
return webpackDevMiddleware;
509541
}
510542

543+
/**
544+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
545+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
546+
* @param {Compiler | MultiCompiler} compiler compiler
547+
* @param {Options<RequestInternal, ResponseInternal>=} options options
548+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} kow wrapper
549+
*/
550+
function koaWrapper(compiler, options) {
551+
return createKoaWrapper(compiler, options, false);
552+
}
553+
554+
/**
555+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
556+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
557+
* @param {Compiler | MultiCompiler} compiler compiler
558+
* @param {Options<RequestInternal, ResponseInternal>=} options options
559+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} kow plugin wrapper
560+
*/
561+
function koaPluginWrapper(compiler, options) {
562+
return createKoaWrapper(compiler, options, true);
563+
}
564+
511565
wdm.koaWrapper = koaWrapper;
566+
wdm.koaPluginWrapper = koaPluginWrapper;
512567

513568
/**
514569
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
515570
* @template {ServerResponse} [ResponseInternal=ServerResponse]
516571
* @param {Compiler | MultiCompiler} compiler compiler
517572
* @param {Options<RequestInternal, ResponseInternal>=} options options
573+
* @param {boolean} usePlugin whether to use as webpack plugin
518574
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} hono wrapper
519575
*/
520-
function honoWrapper(compiler, options) {
576+
function createHonoWrapper(compiler, options, usePlugin = false) {
521577
const devMiddleware = wdm(compiler, options);
522578

579+
if (usePlugin) {
580+
devMiddleware.context.isPlugin = true;
581+
}
582+
523583
/**
524584
* @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
525585
* @param {EXPECTED_FUNCTION} next next function
@@ -685,6 +745,45 @@ function honoWrapper(compiler, options) {
685745
return webpackDevMiddleware;
686746
}
687747

748+
/**
749+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
750+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
751+
* @param {Compiler | MultiCompiler} compiler compiler
752+
* @param {Options<RequestInternal, ResponseInternal>=} options options
753+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} hono wrapper
754+
*/
755+
function honoWrapper(compiler, options) {
756+
return createHonoWrapper(compiler, options, false);
757+
}
758+
759+
/**
760+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
761+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
762+
* @param {Compiler | MultiCompiler} compiler compiler
763+
* @param {Options<RequestInternal, ResponseInternal>=} options options
764+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} hono plugin wrapper
765+
*/
766+
function honoPluginWrapper(compiler, options) {
767+
return createHonoWrapper(compiler, options, true);
768+
}
769+
688770
wdm.honoWrapper = honoWrapper;
771+
wdm.honoPluginWrapper = honoPluginWrapper;
772+
773+
/**
774+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
775+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
776+
* @param {Compiler | MultiCompiler} compiler compiler
777+
* @param {Options<RequestInternal, ResponseInternal>=} options options
778+
* @returns {API<RequestInternal, ResponseInternal>} webpack dev middleware
779+
*/
780+
function plugin(compiler, options = {}) {
781+
const instance = wdm(compiler, options);
782+
// Mark that wdm is used as webpack plugin (to use logger instead of console.log)
783+
instance.context.isPlugin = true;
784+
return instance;
785+
}
786+
787+
wdm.plugin = plugin;
689788

690789
module.exports = wdm;

src/utils/setupHooks.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,13 @@ function setupHooks(context) {
138138

139139
// Avoid extra empty line when `stats: 'none'`
140140
if (printedStats) {
141-
// eslint-disable-next-line no-console
142-
console.log(printedStats);
141+
if (context.isPlugin) {
142+
// Use logger when used as webpack plugin
143+
logger.log(printedStats);
144+
} else {
145+
// eslint-disable-next-line no-console
146+
console.log(printedStats);
147+
}
143148
}
144149

145150
context.callbacks = [];

types/index.d.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,12 @@ declare function wdm<
165165
declare namespace wdm {
166166
export {
167167
hapiWrapper,
168+
hapiPluginWrapper,
168169
koaWrapper,
170+
koaPluginWrapper,
169171
honoWrapper,
172+
honoPluginWrapper,
173+
plugin,
170174
Schema,
171175
Compiler,
172176
MultiCompiler,
@@ -231,6 +235,15 @@ declare function hapiWrapper<
231235
HapiServer,
232236
HapiOptionsInternal extends HapiOptions,
233237
>(): HapiPlugin<HapiServer, HapiOptionsInternal>;
238+
/**
239+
* @template HapiServer
240+
* @template {HapiOptions} HapiOptionsInternal
241+
* @returns {HapiPlugin<HapiServer, HapiOptionsInternal>} hapi plugin wrapper
242+
*/
243+
declare function hapiPluginWrapper<
244+
HapiServer,
245+
HapiOptionsInternal extends HapiOptions,
246+
>(): HapiPlugin<HapiServer, HapiOptionsInternal>;
234247
/**
235248
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
236249
* @template {ServerResponse} [ResponseInternal=ServerResponse]
@@ -245,6 +258,20 @@ declare function koaWrapper<
245258
compiler: Compiler | MultiCompiler,
246259
options?: Options<RequestInternal, ResponseInternal> | undefined,
247260
): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void;
261+
/**
262+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
263+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
264+
* @param {Compiler | MultiCompiler} compiler compiler
265+
* @param {Options<RequestInternal, ResponseInternal>=} options options
266+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} kow plugin wrapper
267+
*/
268+
declare function koaPluginWrapper<
269+
RequestInternal extends IncomingMessage = import("http").IncomingMessage,
270+
ResponseInternal extends ServerResponse = ServerResponse,
271+
>(
272+
compiler: Compiler | MultiCompiler,
273+
options?: Options<RequestInternal, ResponseInternal> | undefined,
274+
): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void;
248275
/**
249276
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
250277
* @template {ServerResponse} [ResponseInternal=ServerResponse]
@@ -259,6 +286,34 @@ declare function honoWrapper<
259286
compiler: Compiler | MultiCompiler,
260287
options?: Options<RequestInternal, ResponseInternal> | undefined,
261288
): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void;
289+
/**
290+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
291+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
292+
* @param {Compiler | MultiCompiler} compiler compiler
293+
* @param {Options<RequestInternal, ResponseInternal>=} options options
294+
* @returns {(ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void} hono plugin wrapper
295+
*/
296+
declare function honoPluginWrapper<
297+
RequestInternal extends IncomingMessage = import("http").IncomingMessage,
298+
ResponseInternal extends ServerResponse = ServerResponse,
299+
>(
300+
compiler: Compiler | MultiCompiler,
301+
options?: Options<RequestInternal, ResponseInternal> | undefined,
302+
): (ctx: EXPECTED_ANY, next: EXPECTED_FUNCTION) => Promise<void> | void;
303+
/**
304+
* @template {IncomingMessage} [RequestInternal=IncomingMessage]
305+
* @template {ServerResponse} [ResponseInternal=ServerResponse]
306+
* @param {Compiler | MultiCompiler} compiler compiler
307+
* @param {Options<RequestInternal, ResponseInternal>=} options options
308+
* @returns {API<RequestInternal, ResponseInternal>} webpack dev middleware
309+
*/
310+
declare function plugin<
311+
RequestInternal extends IncomingMessage = import("http").IncomingMessage,
312+
ResponseInternal extends ServerResponse = ServerResponse,
313+
>(
314+
compiler: Compiler | MultiCompiler,
315+
options?: Options<RequestInternal, ResponseInternal> | undefined,
316+
): API<RequestInternal, ResponseInternal>;
262317
type Schema = import("schema-utils/declarations/validate").Schema;
263318
type Compiler = import("webpack").Compiler;
264319
type MultiCompiler = import("webpack").MultiCompiler;

0 commit comments

Comments
 (0)