From 690a9c98334db8eafd099f1605fd3561de8ee867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 20 Apr 2026 11:35:09 +0200 Subject: [PATCH] prevent `.cache` directory from being copied during node_modules bundling; ensure consistent filtering through absolute path checks --- tools/isobuild/builder.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tools/isobuild/builder.js b/tools/isobuild/builder.js index d0afb2b41b..ff74ccbf75 100644 --- a/tools/isobuild/builder.js +++ b/tools/isobuild/builder.js @@ -538,28 +538,35 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}` // assert.strictEqual(files.pathBasename(options.from), "node_modules"); assert.strictEqual(files.pathBasename(options.to), "node_modules"); + const absFrom = realpath(options.from); + // Bundler scratch written during the build; transient and not part + // of the bundle. Matched by absolute path so a `.cache/` shipped + // inside a published package isn't dropped. + const rootCache = files.pathJoin(absFrom, ".cache"); + if (options.symlink) { // If we're going to use symlinks to speed up this copy, then we // need to make sure we've reserved all directories that are not // package directories, such as the node_modules directory itself, // as well as node_modules/meteor and the parent directories of any // scoped npm packages. - this._ensureAllNonPackageDirectories( - realpath(options.from), - options.to - ); + this._ensureAllNonPackageDirectories(absFrom, options.to, rootCache); } - // Exclude node_modules/.cache: transient bundler scratch space that - // races with readdir (ENOENT) and doesn't belong in the bundle. + const userFilter = options.filter; // Call this._copyDirectory rather than this.copyDirectory so that the // subBuilder hacks from Builder#enter won't apply a second time. return this._copyDirectory(Object.assign({}, options, { - ignore: [/^\.cache\/$/].concat(options.ignore || []), + filter: (absPath, isDirectory) => { + if (isDirectory && absPath === rootCache) return false; + return userFilter ? userFilter(absPath, isDirectory) : true; + }, })); } - _ensureAllNonPackageDirectories(absFromDir, relToDir) { + _ensureAllNonPackageDirectories(absFromDir, relToDir, skipPath) { + if (skipPath && absFromDir === skipPath) return; + const dirStat = optimisticStatOrNull(absFromDir); if (! (dirStat && dirStat.isDirectory())) { return; @@ -589,11 +596,10 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}` } entries.forEach(item => { - // Skip node_modules/.cache (see copyNodeModulesDirectory). - if (item === ".cache") return; this._ensureAllNonPackageDirectories( files.pathJoin(absFromDir, item), - files.pathJoin(relToDir, item) + files.pathJoin(relToDir, item), + skipPath ); }); }