Skip to content

Commit 2bba45b

Browse files
Refine build helpers and docs for recent feedback
- add env-controlled symlink resolution and clarify thread timeout rationale\n- harden cache compression parsing, Sass loader options, and CSS detection\n- document new BUILD_RESOLVE_SYMLINKS flag and validate build/dev flows\n\nTests: npm run build; BUILD_WATCH_ONCE=1 npm run dev
1 parent f9549b6 commit 2bba45b

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ Always reference these instructions first and fall back to search or bash comman
3131
- BUILD_WATCH_ONCE (dev): When set, `npm run dev` runs a single build and exits (useful for timing)
3232
- BUILD_POOL_TIMEOUT: Override thread-loader production pool timeout (ms)
3333
- Default: `2000`. Increase if workers recycle too aggressively on slow machines/CI
34+
- BUILD_RESOLVE_SYMLINKS: When set to `1`/`true`, re-enable Webpack symlink resolution for `npm link`/pnpm workspace development (default off to avoid duplicate module instances)
3435
- Source maps (dev): Dev builds emit external `.map` files next to JS bundles for CSP-safe debugging; production builds disable source maps
35-
- Symlinks: Webpack uses `resolve.symlinks: false` to improve performance and ensure consistent module identity; if you rely on `npm link`/pnpm workspaces, temporarily enable symlink resolution while developing linked packages
36+
- Symlinks: Webpack uses `resolve.symlinks: false` to improve performance and ensure consistent module identity; use `BUILD_RESOLVE_SYMLINKS=1` when you need to work with linked dependencies locally
3637

3738
Performance defaults: esbuild handles JS/CSS minification. In development, CSS is injected via style-loader; in production, CSS is extracted via MiniCssExtractPlugin. Thread-loader is enabled by default in both dev and prod.
3839

build.mjs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const parallelBuild = getBooleanEnv(process.env.BUILD_PARALLEL, true)
3939
const isWatchOnce = getBooleanEnv(process.env.BUILD_WATCH_ONCE, false)
4040
// Cache compression control: default none; allow override via env
4141
function parseCacheCompressionOption(envVal) {
42-
if (envVal == null) return undefined
42+
if (envVal == null) return false
4343
const v = String(envVal).trim().toLowerCase()
4444
if (v === '' || v === '0' || v === 'false' || v === 'none') return false
4545
if (v === 'gzip' || v === 'brotli') return v
@@ -73,6 +73,7 @@ function parseThreadWorkerCount(envValue, cpuCount) {
7373
}
7474
const threadWorkers = parseThreadWorkerCount(process.env.BUILD_THREAD_WORKERS, cpuCount)
7575
// Thread-loader pool timeout constants (allow override via env)
76+
// Keep worker pool warm briefly to amortize repeated builds while still exiting quickly in CI
7677
let PRODUCTION_POOL_TIMEOUT_MS = 2000
7778
if (process.env.BUILD_POOL_TIMEOUT) {
7879
const n = parseInt(process.env.BUILD_POOL_TIMEOUT, 10)
@@ -86,6 +87,8 @@ if (process.env.BUILD_POOL_TIMEOUT) {
8687
}
8788
// Enable threads by default; allow disabling via BUILD_THREAD=0/false/no/off
8889
const enableThread = getBooleanEnv(process.env.BUILD_THREAD, true)
90+
// Allow opt-in symlink resolution for linked/workspace development when needed
91+
const resolveSymlinks = getBooleanEnv(process.env.BUILD_RESOLVE_SYMLINKS, false)
8992

9093
// Cache and resolve Sass implementation once per process
9194
let sassImplPromise
@@ -173,7 +176,7 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
173176
// unnecessary cache invalidations across machines/CI runners
174177
version: JSON.stringify({ PROD: isProduction }),
175178
// default none; override via BUILD_CACHE_COMPRESSION=gzip|brotli
176-
compression: cacheCompressionOption ?? false,
179+
compression: cacheCompressionOption,
177180
buildDependencies: {
178181
config: [
179182
path.resolve('build.mjs'),
@@ -231,9 +234,8 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
231234
],
232235
resolve: {
233236
extensions: ['.jsx', '.mjs', '.js'],
234-
// Disable symlink resolution for consistent behavior/perf; note this can
235-
// affect `npm link`/pnpm workspaces during local development
236-
symlinks: false,
237+
// Disable symlink resolution for consistent behavior/perf; enable via BUILD_RESOLVE_SYMLINKS=1 when working with linked deps
238+
symlinks: resolveSymlinks,
237239
alias: {
238240
parse5: path.resolve(__dirname, 'node_modules/parse5'),
239241
...(minimal
@@ -303,7 +305,12 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
303305
},
304306
{
305307
loader: 'sass-loader',
306-
options: { implementation: sassImpl },
308+
options: {
309+
implementation: sassImpl,
310+
sassOptions: {
311+
silentDeps: true,
312+
},
313+
},
307314
},
308315
],
309316
},
@@ -510,7 +517,7 @@ async function copyFiles(entryPoints, targetDir) {
510517
try {
511518
await fs.copy(entryPoint.src, `${targetDir}/${entryPoint.dst}`)
512519
} catch (e) {
513-
const isCss = String(entryPoint.dst).endsWith('.css')
520+
const isCss = typeof entryPoint.dst === 'string' && entryPoint.dst.endsWith('.css')
514521
if (e && e.code === 'ENOENT') {
515522
if (!isProduction && isCss) {
516523
console.log(

0 commit comments

Comments
 (0)