Skip to content

Commit

Permalink
feat: Webpack Memory Cache (#190)
Browse files Browse the repository at this point in the history
* Enable webpack in-memory cache

* Changeset files

* remove caching from build configuration and update documentation

* remove a leftover failing test

* remove snapshot overrides and unnecessary cache default value

---------

Co-authored-by: Brian Sokol <[email protected]>
  • Loading branch information
bsokol-wl and bsokol-wl authored Mar 25, 2024
1 parent 71a58b2 commit b6246b3
Show file tree
Hide file tree
Showing 7 changed files with 10 additions and 167 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-papayas-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@workleap/webpack-configs": minor
---

Enable in-memory webpack cache by default
37 changes: 0 additions & 37 deletions docs/webpack/configure-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,43 +203,6 @@ export default defineBuildConfig(swcConfig, {
});
```

### `cache`

- **Type**: `boolean`
- **Default**: `true`

Whether or not webpack [filesystem cache](https://webpack.js.org/configuration/cache/) is enabled.

```js !#7 webpack.build.js
// @ts-check

import { defineDevConfig } from "@workleap/webpack-configs";
import { swcConfig } from "./swc.build.js";

export default defineBuildConfig(swcConfig, {
cache: false
});
```

### `cacheDirectory`

- **Type**: `string`
- **Default**: `node_modules/.cache/webpack`

```js !#8 webpack.build.js
// @ts-check

import { defineBuildConfig } from "@workleap/webpack-configs";
import { swcConfig } from "./swc.build.js";
import path from "path";

export default defineBuildConfig(swcConfig, {
cacheDirectory: path.resolve("./custom-webpack-cache")
});
```

Set webpack [cacheDirectory option](https://webpack.js.org/configuration/cache/#cachecachedirectory) when `cache` is enabled.

### `moduleRules`

- **Type**: An array of webpack [moduleRule](https://webpack.js.org/configuration/module/#modulerules) objects
Expand Down
21 changes: 1 addition & 20 deletions docs/webpack/configure-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export default defineDevConfig(swcConfig, {
- **Type**: `boolean`
- **Default**: `true`

Whether or not webpack [filesystem cache](https://webpack.js.org/configuration/cache/) is enabled.
Whether or not webpack [memory cache](https://webpack.js.org/configuration/cache/#cache) is enabled. This will also set [maxGenerations](https://webpack.js.org/configuration/cache/#cachemaxgenerations) to 1 to remove cache entries from memory when they are no longer needed.

```js !#7 webpack.dev.js
// @ts-check
Expand All @@ -257,25 +257,6 @@ export default defineDevConfig(swcConfig, {
});
```

### `cacheDirectory`

- **Type**: `string`
- **Default**: `node_modules/.cache/webpack`

```js !#8 webpack.dev.js
// @ts-check

import { defineDevConfig } from "@workleap/webpack-configs";
import { swcConfig } from "./swc.dev.js";
import path from "path";

export default defineDevConfig(swcConfig, {
cacheDirectory: path.resolve("./custom-webpack-cache")
});
```

Set webpack [cacheDirectory option](https://webpack.js.org/configuration/cache/#cachecachedirectory) when `cache` is enabled.

### `moduleRules`

- **Type**: An array of webpack [moduleRule](https://webpack.js.org/configuration/module/#modulerules) objects
Expand Down
39 changes: 0 additions & 39 deletions packages/webpack-configs/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import TerserPlugin from "terser-webpack-plugin";
import type { Configuration as WebpackConfig } from "webpack";
import webpack from "webpack";
Expand All @@ -19,9 +18,6 @@ const DefinePlugin = webpack.DefinePlugin;
// is available
const require = createRequire(import.meta.url);

// The equivalent of __filename for CommonJS.
const __filename = fileURLToPath(import.meta.url);

export function defineBuildHtmlWebpackPluginConfig(options: HtmlWebpackPlugin.Options = {}): HtmlWebpackPlugin.Options {
const {
template = path.resolve("./public/index.html"),
Expand Down Expand Up @@ -107,8 +103,6 @@ export interface DefineBuildConfigOptions {
entry?: string;
outputPath?: string;
publicPath?: `${string}/` | "auto";
cache?: boolean;
cacheDirectory?: string;
moduleRules?: NonNullable<WebpackConfig["module"]>["rules"];
plugins?: WebpackConfig["plugins"];
htmlWebpackPlugin?: boolean | HtmlWebpackPlugin.Options;
Expand All @@ -127,8 +121,6 @@ export function defineBuildConfig(swcConfig: SwcConfig, options: DefineBuildConf
outputPath = path.resolve("dist"),
// The trailing / is very important, otherwise paths will not be resolved correctly.
publicPath = "http://localhost:8080/",
cache = true,
cacheDirectory = path.resolve("node_modules/.cache/webpack"),
moduleRules = [],
plugins = [],
htmlWebpackPlugin = defineBuildHtmlWebpackPluginConfig(),
Expand All @@ -153,37 +145,6 @@ export function defineBuildConfig(swcConfig: SwcConfig, options: DefineBuildConf
publicPath,
clean: true
},
cache: cache && {
type: "filesystem",
allowCollectingMemory: false,
cacheDirectory: cacheDirectory,
maxMemoryGenerations: 1,
// Took from https://webpack.js.org/configuration/cache/#cachebuilddependencies.
buildDependencies: {
config: [__filename]
}
},
// (ACTUALLY NOT FIXING ANYTHING AT THE MOMENT)
// Fixes caching for environmental variables using the DefinePlugin by forcing
// webpack caching to prioritize hashes over timestamps.
snapshot: cache ? {
buildDependencies: {
hash: true,
timestamp: true
},
module: {
hash: true,
timestamp: true
},
resolve: {
hash: true,
timestamp: true
},
resolveBuildDependencies: {
hash: true,
timestamp: true
}
} : undefined,
optimization: getOptimizationConfig(optimize),
infrastructureLogging: verbose ? {
appendOnly: true,
Expand Down
37 changes: 2 additions & 35 deletions packages/webpack-configs/src/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type { Config as SwcConfig } from "@swc/core";
import HtmlWebpackPlugin from "html-webpack-plugin";
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import type { Configuration as WebpackConfig } from "webpack";
import webpack from "webpack";
import type { ServerOptions } from "webpack-dev-server";
Expand All @@ -23,9 +22,6 @@ const DefinePlugin = webpack.DefinePlugin;
// is available
const require = createRequire(import.meta.url);

// The equivalent of __filename for CommonJS.
const __filename = fileURLToPath(import.meta.url);

export function defineDevHtmlWebpackPluginConfig(options: HtmlWebpackPlugin.Options = {}): HtmlWebpackPlugin.Options {
const {
template = path.resolve("./public/index.html"),
Expand All @@ -49,7 +45,6 @@ export interface DefineDevConfigOptions {
port?: number;
publicPath?: `${string}/` | "auto";
cache?: boolean;
cacheDirectory?: string;
moduleRules?: NonNullable<WebpackConfig["module"]>["rules"];
plugins?: WebpackConfig["plugins"];
htmlWebpackPlugin?: boolean | HtmlWebpackPlugin.Options;
Expand Down Expand Up @@ -94,7 +89,6 @@ export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOp
port = 8080,
publicPath,
cache = true,
cacheDirectory = path.resolve("node_modules/.cache/webpack"),
moduleRules = [],
plugins = [],
htmlWebpackPlugin = defineDevHtmlWebpackPluginConfig(),
Expand Down Expand Up @@ -134,36 +128,9 @@ export function defineDevConfig(swcConfig: SwcConfig, options: DefineDevConfigOp
publicPath: publicPath ?? `${https ? "https" : "http"}://${host}:${port}/`
},
cache: cache && {
type: "filesystem",
allowCollectingMemory: true,
maxMemoryGenerations: 1,
cacheDirectory: cacheDirectory,
// Took from https://webpack.js.org/configuration/cache/#cachebuilddependencies.
buildDependencies: {
config: [__filename]
}
type: "memory",
maxGenerations: 1
},
// (ACTUALLY NOT FIXING ANYTHING AT THE MOMENT)
// Fixes caching for environmental variables using the DefinePlugin by forcing
// webpack caching to prioritize hashes over timestamps.
snapshot: cache ? {
buildDependencies: {
hash: true,
timestamp: true
},
module: {
hash: true,
timestamp: true
},
resolve: {
hash: true,
timestamp: true
},
resolveBuildDependencies: {
hash: true,
timestamp: true
}
} : undefined,
// See: https://webpack.js.org/guides/build-performance/#avoid-extra-optimization-steps
optimization: {
// Keep "runtimeChunk" to false, otherwise it breaks module federation
Expand Down
27 changes: 1 addition & 26 deletions packages/webpack-configs/tests/build.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineBuildConfig as defineSwcConfig } from "@workleap/swc-configs";
import HtmlWebpackPlugin from "html-webpack-plugin";
import type { Configuration, FileCacheOptions, RuleSetRule } from "webpack";
import type { Configuration, RuleSetRule } from "webpack";
import { defineBuildConfig, defineBuildHtmlWebpackPluginConfig, defineMiniCssExtractPluginConfig } from "../src/build.ts";
import type { WebpackConfigTransformer } from "../src/transformers/applyTransformers.ts";
import { findModuleRule, matchAssetModuleType, matchLoaderName } from "../src/transformers/moduleRules.ts";
Expand Down Expand Up @@ -171,31 +171,6 @@ test("when optimize is \"readable\", include minify configuration", () => {
expect(result.optimization?.minimizer).toBeDefined();
});

test("when cache is enabled, the cache configuration is included", () => {
const result = defineBuildConfig(SwcConfig, {
cache: true
});

expect(result.cache).toBeDefined();
});

test("when cache is disabled, the cache prop is false", () => {
const result = defineBuildConfig(SwcConfig, {
cache: false
});

expect(result.cache).toBeFalsy();
});

test("when a cache directory is provided and cache is enabled, use the provided cache directory value", () => {
const result = defineBuildConfig(SwcConfig, {
cache: true,
cacheDirectory: "a-custom-path"
});

expect((result.cache as FileCacheOptions).cacheDirectory).toBe("a-custom-path");
});

test("when htmlWebpackPlugin is \"false\", no html-webpack-plugin instance is added to the plugin array", () => {
const config = defineBuildConfig(SwcConfig, {
htmlWebpackPlugin: false
Expand Down
11 changes: 1 addition & 10 deletions packages/webpack-configs/tests/dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import type { 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 { Configuration, RuleSetRule } from "webpack";
import type { ClientConfiguration, ServerConfiguration } from "webpack-dev-server";
import { defineDevConfig, defineDevHtmlWebpackPluginConfig, defineFastRefreshPluginConfig } from "../src/dev.ts";
import type { WebpackConfigTransformer } from "../src/transformers/applyTransformers.ts";
Expand Down Expand Up @@ -109,15 +109,6 @@ test("when cache is disabled, the cache prop is false", () => {
expect(result.cache).toBeFalsy();
});

test("when a cache directory is provided and cache is enabled, use the provided cache directory value", () => {
const result = defineDevConfig(DefaultConfig, {
cache: true,
cacheDirectory: "a-custom-path"
});

expect((result.cache as FileCacheOptions).cacheDirectory).toBe("a-custom-path");
});

test("when additional module rules are provided, append the provided rules at the end of the module rules array", () => {
const newModuleRule1 = {
test: /\.svg/i,
Expand Down

0 comments on commit b6246b3

Please sign in to comment.