Skip to content

Commit 53fbb7e

Browse files
committed
feat(webpack): add webpackFilesystemCache for production builds
Allow opting in to Webpack filesystem cache for sku build / build-ssr and CI via sku.config or SKU_WEBPACK_FILESYSTEM_CACHE. Default remains development-only (dev server). Made-with: Cursor
1 parent 537dad5 commit 53fbb7e

11 files changed

Lines changed: 102 additions & 15 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sku': minor
3+
---
4+
5+
`webpack`: Add `webpackFilesystemCache` (`'development' | 'always'`) so production builds (`sku build` / `sku build-ssr`) and CI can opt in to Webpack filesystem caching. Override with `SKU_WEBPACK_FILESYSTEM_CACHE`. Default remains `'development'` (cache only for the local dev server).

docs/docs/configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,16 @@ Unfortunately, these kinds of imports only work for apps. In packages, the impor
492492

493493
You can set this option in `sku.config.js`, or adding `"skuCompilePackage": true` to your `package.json` will disable this behaviour by default.
494494

495+
## webpackFilesystemCache
496+
497+
Type: `'development' | 'always'`
498+
499+
Default: `'development'`
500+
501+
Bundler: `webpack`
502+
503+
Controls Webpack’s [filesystem cache](https://webpack.js.org/configuration/cache/#cachetype). With `'development'`, the cache is used only for the local dev server. Set to `'always'` to also use it for production builds and in CI (unless `SKU_DISABLE_CACHE` is set). Override with `SKU_WEBPACK_FILESYSTEM_CACHE=development` or `SKU_WEBPACK_FILESYSTEM_CACHE=always`. See [Caching](./extra-features?id=caching) for Docker and CI notes.
504+
495505
## routes
496506

497507
Type: `Array<string | {route: string, name: string, entry: string, languages: Array<string>}>`

docs/docs/extra-features.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,16 @@ export default {
156156
### [Webpack filesystem cache]
157157

158158
This cache stores generated webpack modules and chunks.
159-
It is only emitted during local development.
160-
Its purpose is to reduce the time it takes to start the local development server.
159+
By default (`webpackFilesystemCache: 'development'` in `sku.config.ts`), it is only used for the local development server (`sku start` / `sku start-ssr`).
160+
161+
Set `webpackFilesystemCache: 'always'` to also enable it for `sku build` / `sku build-ssr` (including in CI), unless `SKU_DISABLE_CACHE` is set. You can override the config with `SKU_WEBPACK_FILESYSTEM_CACHE=development` or `SKU_WEBPACK_FILESYSTEM_CACHE=always`.
162+
163+
In Docker or Buildkite, pair `'always'` with a [BuildKit cache mount] on `node_modules/.cache/webpack` so the cache persists between image builds on the same agents.
161164

162165
> This cache is stored in `node_modules/.cache/webpack` and can be safely deleted at any time.
163166
164167
[webpack filesystem cache]: https://webpack.js.org/configuration/cache/#cachetype
168+
[BuildKit cache mount]: https://docs.docker.com/build/cache/optimize/#use-cache-mounts
165169

166170
### [`babel-loader` cache]
167171

packages/sku/src/context/configSchema.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ export default validator.compile({
197197
rootResolution: {
198198
type: 'boolean',
199199
},
200+
webpackFilesystemCache: {
201+
type: 'enum',
202+
values: ['development', 'always'],
203+
optional: true,
204+
},
200205
languages: languagesToCompile,
201206
skipPackageCompatibilityCompilation: {
202207
type: 'array',

packages/sku/src/context/createSkuContext.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import type { SkuConfig, SkuRoute, SkuRouteObject } from '../types/types.js';
1+
import type {
2+
SkuConfig,
3+
SkuRoute,
4+
SkuRouteObject,
5+
WebpackFilesystemCacheMode,
6+
} from '../types/types.js';
27
import { getPathFromCwd, requireFromCwd } from '@sku-private/utils';
38
import { existsSync } from 'node:fs';
49
import defaultSkuConfig from './defaultSkuConfig.js';
@@ -257,6 +262,13 @@ export const createSkuContext = ({
257262
skuConfig.skipPackageCompatibilityCompilation;
258263
const externalizeNodeModules = skuConfig.externalizeNodeModules;
259264

265+
const envWebpackFilesystemCache = process.env.SKU_WEBPACK_FILESYSTEM_CACHE;
266+
const webpackFilesystemCache: WebpackFilesystemCacheMode =
267+
envWebpackFilesystemCache === 'always' ||
268+
envWebpackFilesystemCache === 'development'
269+
? envWebpackFilesystemCache
270+
: skuConfig.webpackFilesystemCache ?? 'development';
271+
260272
const tsPaths =
261273
skuConfig.bundler === 'vite' || skuConfig.testRunner === 'vitest'
262274
? generateTypeScriptPaths(skuConfig.pathAliases)
@@ -314,6 +326,7 @@ export const createSkuContext = ({
314326
cspExtraScriptSrcHosts,
315327
httpsDevServer,
316328
rootResolution,
329+
webpackFilesystemCache,
317330
languages,
318331
initialPath,
319332
transformOutputPath: skuConfig.transformOutputPath,

packages/sku/src/context/defaultSkuConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default {
4444
httpsDevServer: false,
4545
devServerMiddleware: undefined,
4646
rootResolution: !isCompilePackage,
47+
webpackFilesystemCache: 'development',
4748
languages: undefined,
4849
skipPackageCompatibilityCompilation: [],
4950
externalizeNodeModules: false,

packages/sku/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export type {
33
RenderCallbackParams,
44
Server,
55
SkuConfig,
6+
WebpackFilesystemCacheMode,
67
} from './types/types.js';
Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,41 @@
11
import isCI from '../../../utils/isCI.js';
22
import type { SkuContext } from '../../../context/createSkuContext.js';
3+
import type { WebpackFilesystemCacheMode } from '../../../types/types.js';
34

45
const disableCacheOverride = Boolean(process.env.SKU_DISABLE_CACHE);
56

67
function getWebpackCacheSettings({
78
isDevServer,
89
paths,
10+
webpackFilesystemCache,
911
}: {
1012
isDevServer: boolean;
1113
paths: SkuContext['paths'];
14+
webpackFilesystemCache: WebpackFilesystemCacheMode;
1215
}) {
13-
if (isDevServer && !isCI && !disableCacheOverride) {
14-
return {
15-
type: 'filesystem',
16-
buildDependencies: {
17-
config: paths.appSkuConfigPath ? [paths.appSkuConfigPath] : [],
18-
},
19-
};
16+
if (disableCacheOverride) {
17+
return false;
2018
}
2119

22-
return false;
20+
if (webpackFilesystemCache === 'development') {
21+
if (isDevServer && !isCI) {
22+
return {
23+
type: 'filesystem' as const,
24+
buildDependencies: {
25+
config: paths.appSkuConfigPath ? [paths.appSkuConfigPath] : [],
26+
},
27+
};
28+
}
29+
30+
return false;
31+
}
32+
33+
return {
34+
type: 'filesystem' as const,
35+
buildDependencies: {
36+
config: paths.appSkuConfigPath ? [paths.appSkuConfigPath] : [],
37+
},
38+
};
2339
}
2440

2541
export default getWebpackCacheSettings;

packages/sku/src/services/webpack/config/webpack.config.ssr.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const makeWebpackConfig = ({
5151
skipPackageCompatibilityCompilation,
5252
externalizeNodeModules,
5353
sourceMapsProd,
54+
webpackFilesystemCache,
5455
} = skuContext;
5556
const isProductionBuild = process.env.NODE_ENV === 'production';
5657
const webpackMode = isProductionBuild ? 'production' : 'development';
@@ -94,7 +95,11 @@ const makeWebpackConfig = ({
9495
filename: `${fileMask}.js`,
9596
chunkFilename: `${fileMask}.js`,
9697
},
97-
cache: getCacheSettings({ isDevServer, paths }),
98+
cache: getCacheSettings({
99+
isDevServer,
100+
paths,
101+
webpackFilesystemCache,
102+
}),
98103
optimization: {
99104
nodeEnv: process.env.NODE_ENV,
100105
minimize: isProductionBuild,
@@ -248,7 +253,11 @@ const makeWebpackConfig = ({
248253
hotUpdateChunkFilename: `[id].[fullhash].hot-update.${type === 'module' ? 'c' : ''}js`,
249254
library: { name: 'server', type: 'var' },
250255
},
251-
cache: getCacheSettings({ isDevServer, paths }),
256+
cache: getCacheSettings({
257+
isDevServer,
258+
paths,
259+
webpackFilesystemCache,
260+
}),
252261
optimization: {
253262
nodeEnv: process.env.NODE_ENV,
254263
emitOnErrors: isProductionBuild,

packages/sku/src/services/webpack/config/webpack.config.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const makeWebpackConfig = ({
5656
skipPackageCompatibilityCompilation,
5757
externalizeNodeModules,
5858
sourceMapsProd,
59+
webpackFilesystemCache,
5960
} = skuContext;
6061
const isProductionBuild = process.env.NODE_ENV === 'production';
6162

@@ -134,7 +135,11 @@ const makeWebpackConfig = ({
134135
}
135136
: {}),
136137
},
137-
cache: getCacheSettings({ isDevServer, paths }),
138+
cache: getCacheSettings({
139+
isDevServer,
140+
paths,
141+
webpackFilesystemCache,
142+
}),
138143
optimization: {
139144
nodeEnv: process.env.NODE_ENV,
140145
minimize: isProductionBuild,
@@ -292,7 +297,11 @@ const makeWebpackConfig = ({
292297
filename: 'render.js',
293298
library: { name: 'static', type: 'umd2', export: 'default' },
294299
},
295-
cache: getCacheSettings({ isDevServer, paths }),
300+
cache: getCacheSettings({
301+
isDevServer,
302+
paths,
303+
webpackFilesystemCache,
304+
}),
296305
optimization: {
297306
nodeEnv: process.env.NODE_ENV,
298307
},

0 commit comments

Comments
 (0)