diff --git a/.changeset/old-turtles-prove.md b/.changeset/old-turtles-prove.md new file mode 100644 index 00000000..797b588d --- /dev/null +++ b/.changeset/old-turtles-prove.md @@ -0,0 +1,5 @@ +--- +"@workleap/webpack-configs": minor +--- + +Added an overlay predefined options for the webpack config. diff --git a/docs/postcss/configure-project.md b/docs/postcss/configure-project.md index 76282b67..bb8b4177 100644 --- a/docs/postcss/configure-project.md +++ b/docs/postcss/configure-project.md @@ -115,7 +115,7 @@ To view the default configuration of `@workleap/postcss-configs`, have a look at ### `transformers` -- **Type**: `((config: PostCSSConfig ) => PostCSSConfig)[]` +- **Type**: `((config: PostCSSConfig) => PostCSSConfig)[]` - **Default**: `[]` ```ts diff --git a/docs/swc/configure-build.md b/docs/swc/configure-build.md index 6eabbdaf..a1742475 100644 --- a/docs/swc/configure-build.md +++ b/docs/swc/configure-build.md @@ -146,11 +146,11 @@ transformer(config: SwcConfig, context: SwcConfigTransformerContext) => SwcConfi ```js !#7-11,14 swc.build.js // @ts-check -import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs"; +import { browserslistToSwc, defineBuildConfig, type SwcConfigTransformer, type SwcConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -function mangleMinifiedCode(config) { +const mangleMinifiedCode: SwcConfigTransformer = (config: SwcConfig) => { config.jsc.minify.mangle = true; return config; @@ -166,7 +166,7 @@ export const swcConfig = defineBuildConfig(targets, { Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 transformer.ts -import { SwcConfigTransformer, SwcConfigTransformerContext, SwcConfig } from "@workleap/swc-configs"; +import type { SwcConfigTransformer, SwcConfigTransformerContext, SwcConfig } from "@workleap/swc-configs"; export const transformer: SwcConfigTransformer = (config: SwcConfig, context: SwcConfigTransformerContext) => { if (context.environment === "build") { diff --git a/docs/swc/configure-dev.md b/docs/swc/configure-dev.md index e1193946..5a4c9c4e 100644 --- a/docs/swc/configure-dev.md +++ b/docs/swc/configure-dev.md @@ -165,11 +165,11 @@ transformer(config: SwcConfig, context: SwcConfigTransformerContext) => SwcConfi ```js !#7-11,14 swc.dev.js // @ts-check -import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; +import { browserslistToSwc, defineDevConfig, type SwcConfigTransformer, type SwcConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -function disableReactBuiltins(config) { +const disableReactBuiltins: SwcConfigTransformer = (config: SwcConfig) => { config.jsc.transform.react.useBuiltins = false; return config; @@ -185,7 +185,7 @@ export const swcConfig = defineDevConfig(targets, { Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 transformer.ts -import { SwcConfigTransformer, SwcConfigTransformerContext, SwcConfig } from "@workleap/swc-configs"; +import type { SwcConfigTransformer, SwcConfigTransformerContext, SwcConfig } from "@workleap/swc-configs"; export const transformer: SwcConfigTransformer = (config: SwcConfig, context: SwcConfigTransformerContext) => { if (context.environment === "dev") { diff --git a/docs/swc/configure-jest.md b/docs/swc/configure-jest.md index 185c7e3e..d5209087 100644 --- a/docs/swc/configure-jest.md +++ b/docs/swc/configure-jest.md @@ -108,7 +108,7 @@ transformer(config: SwcConfig, context: SwcConfigTransformerContext) => SwcConfi ``` ```ts !#3-7,10 swc.jest.ts -import { defineJestConfig, SwcConfigTransformer, SwcConfig } from "@workleap/swc-configs"; +import { defineJestConfig, type SwcConfigTransformer, type SwcConfig } from "@workleap/swc-configs"; const useCommonJsModules: SwcConfigTransformer = (config: SwcConfig) => { config.module.type = "commonjs"; diff --git a/docs/tsup/configure-build.md b/docs/tsup/configure-build.md index 6b93a7ce..187006bf 100644 --- a/docs/tsup/configure-build.md +++ b/docs/tsup/configure-build.md @@ -77,7 +77,7 @@ To view the default build configuration of `@workleap/tsup-configs`, have a look - **Default**: `[]` ```ts myCustomTransformer.ts -import { TsupConfigTransformer, TsupConfig } from "@workleap/tsup-configs"; +import { type TsupConfigTransformer, type TsupConfig } from "@workleap/tsup-configs"; export const myCustomTsupTransformer: TsupConfigTransformer = (config: TsupConfig) => { config.dts = false; @@ -102,7 +102,7 @@ export default defineBuildConfig({ Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 myCustomTransformer.ts -import { TsupConfigTransformer, TsupConfigTransformerContext, TsupConfig } from "@workleap/tsup-configs"; +import type { TsupConfigTransformer, TsupConfigTransformerContext, TsupConfig } from "@workleap/tsup-configs"; export const myCustomTsupTransformer: TsupConfigTransformer = (config: TsupConfig, context: TsupConfigTransformerContext) => { if (context.environment === "build") { diff --git a/docs/tsup/configure-dev.md b/docs/tsup/configure-dev.md index fe767b67..21851f79 100644 --- a/docs/tsup/configure-dev.md +++ b/docs/tsup/configure-dev.md @@ -77,7 +77,7 @@ To view the default development configuration of `@workleap/tsup-configs`, have - **Default**: `[]` ```ts myCustomTransformer.ts -import { TsupConfigTransformer, TsupConfig } from "@workleap/tsup-configs"; +import { type TsupConfigTransformer, type TsupConfig } from "@workleap/tsup-configs"; export const myCustomTsupTransformer: TsupConfigTransformer = (config: TsupConfig) => { config.dts = false; @@ -102,7 +102,7 @@ export default defineDevConfig({ Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 myCustomTransformer.ts -import { TsupConfigTransformer, TsupConfigTransformerContext, TsupConfig } from "@workleap/tsup-configs"; +import type { TsupConfigTransformer, TsupConfigTransformerContext, TsupConfig } from "@workleap/tsup-configs"; export const transformer: TsupConfigTransformer = (config: TsupConfig, context: TsupConfigTransformerContext) => { if (context.environment === "dev") { diff --git a/docs/webpack/configure-build.md b/docs/webpack/configure-build.md index 86213c99..3c463eff 100644 --- a/docs/webpack/configure-build.md +++ b/docs/webpack/configure-build.md @@ -397,7 +397,7 @@ transformer(config: WebpackConfig, context: WebpackConfigTransformerContext) => ```js !#6-10,13 webpack.build.js // @ts-check -import { defineBuildConfig, WebpackConfigTransformer, WebpackConfig } from "@workleap/webpack-configs"; +import { defineBuildConfig, type WebpackConfigTransformer, type WebpackConfig } from "@workleap/webpack-configs"; import { swcConfig } from "./swc.build.js"; const useContentHashOutputFilename: WebpackConfigTransformer = (config: WebpackConfig) => { @@ -416,7 +416,7 @@ export default defineBuildConfig(swcConfig, { Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 transformer.ts -import { WebpackConfigTransformer, WebpackConfigTransformerContext, WebpackConfig } from "@workleap/webpack-configs"; +import type { WebpackConfigTransformer, WebpackConfigTransformerContext, WebpackConfig } from "@workleap/webpack-configs"; export const transformer: WebpackConfigTransformer = (config: WebpackConfig, context: WebpackConfigTransformerContext) => { if (context.environment === "build") { diff --git a/docs/webpack/configure-dev.md b/docs/webpack/configure-dev.md index 0fa4e38e..f5c7a771 100644 --- a/docs/webpack/configure-dev.md +++ b/docs/webpack/configure-dev.md @@ -368,6 +368,24 @@ export default defineDevConfig(swcConfig, { }); ``` +### `overlay` + +- **Type**: `false` +- **Default**: `undefined` + +Whether or not a full-screen overlay should be in the browser when there are compiler errors or warnings. + +```js !#7 webpack.dev.js +// @ts-check + +import { defineDevConfig } from "@workleap/webpack-configs"; +import { swcConfig } from "./swc.dev.js"; + +export default defineDevConfig(swcConfig, { + overlay: false +}); +``` + ### `verbose` - **Type**: `boolean` @@ -408,7 +426,7 @@ transformer(config: WebpackConfig, context: WebpackConfigTransformerContext) => ```js !#6-12,16 webpack.dev.js // @ts-check -import { defineDevConfig, WebpackConfigTransformer, WebpackConfig } from "@workleap/webpack-configs"; +import { defineDevConfig, type WebpackConfigTransformer, type WebpackConfig } from "@workleap/webpack-configs"; import { swcConfig } from "./swc.dev.js"; const enableInMemoryCache: WebpackConfigTransformer = (config: WebpackConfig) => { @@ -430,7 +448,7 @@ export default defineDevConfig(swcConfig, { Generic transformers can use the `context` parameter to gather additional information about their execution context, like the `environment` they are operating in: ```ts !#4 transformer.ts -import { WebpackConfigTransformer, WebpackConfigTransformerContext, WebpackConfig } from "@workleap/webpack-configs"; +import type { WebpackConfigTransformer, WebpackConfigTransformerContext, WebpackConfig } from "@workleap/webpack-configs"; export const transformer: WebpackConfigTransformer = (config: WebpackConfig, context: WebpackConfigTransformerContext) => { if (context.environment === "dev") { diff --git a/packages/webpack-configs/src/dev.ts b/packages/webpack-configs/src/dev.ts index 483c51c7..52a96e54 100644 --- a/packages/webpack-configs/src/dev.ts +++ b/packages/webpack-configs/src/dev.ts @@ -8,7 +8,7 @@ import { fileURLToPath } from "node:url"; import type { Configuration as WebpackConfig } from "webpack"; import webpack from "webpack"; import { applyTransformers, type WebpackConfigTransformer } from "./transformers/applyTransformers.ts"; -import { isObject } from "./utils.ts"; +import { isNil, isObject } from "./utils.ts"; // Add the "devServer" prop to WebpackConfig typings. import "webpack-dev-server"; @@ -52,6 +52,7 @@ export interface DefineDevConfigOptions { htmlWebpackPlugin?: boolean | HtmlWebpackPlugin.Options; fastRefresh?: boolean | ReactRefreshPluginOptions; cssModules?: boolean; + overlay?: false; environmentVariables?: Record; transformers?: WebpackConfigTransformer[]; verbose?: boolean; @@ -71,6 +72,14 @@ function trySetSwcFastRefresh(config: SwcConfig, enabled: boolean) { return config; } +function trySetFastRefreshOverlay(options: ReactRefreshPluginOptions, overlay?: boolean) { + if (overlay === false && isNil(options.overlay)) { + options.overlay = false; + } + + return options; +} + export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOptions = {}) { preflight(); @@ -86,6 +95,7 @@ export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOp htmlWebpackPlugin = defineDevHtmlWebpackPluginConfig(), fastRefresh = true, cssModules = false, + overlay, // Using an empty object literal as the default value to ensure // "process.env" is always available. environmentVariables = {}, @@ -104,7 +114,10 @@ export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOp https, host, port, - historyApiFallback: true + historyApiFallback: true, + client: (overlay === false || fastRefresh) ? { + overlay: false + } : undefined }, entry, output: { @@ -220,7 +233,7 @@ export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOp return acc; }, {} as Record) }), - fastRefresh && new ReactRefreshWebpackPlugin(isObject(fastRefresh) ? fastRefresh : defineFastRefreshPluginConfig()), + fastRefresh && new ReactRefreshWebpackPlugin(trySetFastRefreshOverlay(isObject(fastRefresh) ? fastRefresh : defineFastRefreshPluginConfig(), overlay)), ...plugins ].filter(Boolean) as WebpackConfig["plugins"] }; diff --git a/packages/webpack-configs/src/utils.ts b/packages/webpack-configs/src/utils.ts index 51f8e36d..cdd19895 100644 --- a/packages/webpack-configs/src/utils.ts +++ b/packages/webpack-configs/src/utils.ts @@ -2,3 +2,18 @@ export function isObject(value: any): value is Record { return typeof value === "object" && !Array.isArray(value) && value != null; } + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function isNull(value: any): value is null { + return value == null; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function isUndefined(value: any): value is undefined { + return typeof value === "undefined" || value === undefined; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function isNil(value: any): value is null | undefined { + return isNull(value) || isUndefined(value); +} diff --git a/packages/webpack-configs/tests/dev.test.ts b/packages/webpack-configs/tests/dev.test.ts index 2b385cf0..8fbd5cdc 100644 --- a/packages/webpack-configs/tests/dev.test.ts +++ b/packages/webpack-configs/tests/dev.test.ts @@ -3,6 +3,7 @@ import { Config as SwcConfig } from "@swc/core"; import { defineDevConfig as defineSwcConfig } from "@workleap/swc-configs"; import HtmlWebpackPlugin from "html-webpack-plugin"; import type { Configuration, FileCacheOptions, RuleSetRule } from "webpack"; +import type { ClientConfiguration } from "webpack-dev-server"; import { defineDevConfig, defineDevHtmlWebpackPluginConfig, defineFastRefreshPluginConfig } from "../src/dev.ts"; import type { WebpackConfigTransformer } from "../src/transformers/applyTransformers.ts"; import { findModuleRule, matchLoaderName } from "../src/transformers/moduleRules.ts"; @@ -251,6 +252,30 @@ test("when css modules is disabled, do not include css modules configuration", ( expect((cssLoader?.moduleRule as RuleSetRule).options).toBeUndefined(); }); +test("when the overlay option is not provided and fast refresh is disabled, the devserver overlay option is undefined", () => { + const result = defineDevConfig(SwcConfig, { + fastRefresh: false + }); + + expect(result.devServer!.client).toBeUndefined(); +}); + +test("when fast refresh is enabled, the devserver overlay option is false", () => { + const result = defineDevConfig(SwcConfig, { + fastRefresh: true + }); + + expect((result.devServer!.client as ClientConfiguration).overlay).toBeFalsy(); +}); + +test("when the overlay is disabled, the devserver overlay option is false", () => { + const result = defineDevConfig(SwcConfig, { + overlay: false + }); + + expect((result.devServer!.client as ClientConfiguration).overlay).toBeFalsy(); +}); + test("the provided swc config object is set as the swc-loader options", () => { const swcConfig = SwcConfig;