Skip to content

Commit 9e4bdb9

Browse files
committed
remove files from dist once deleted from src
1 parent bb894a9 commit 9e4bdb9

2 files changed

Lines changed: 77 additions & 9 deletions

File tree

src/core/postbuild.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,73 @@ export async function copyRequiredFiles() {
4848
await Promise.all(task);
4949
}
5050

51+
// function to unlink files from build path, this expect files paths exist in src
52+
// this used when watch mode is enabled and we need to unlink files from build path
53+
// when file is deleted in src path
54+
export async function unlinkFilesFormBuild(
55+
files: string | string[],
56+
isDir: boolean = false,
57+
) {
58+
const { srcPath, lib } = getConfig();
59+
60+
const cjsPath = lib?.cjs?.output?.path;
61+
const esmPath = lib?.esm?.output?.path;
62+
63+
const hasCJS = fse.pathExistsSync(cjsPath);
64+
const hasESM = fse.pathExistsSync(esmPath);
65+
66+
const tasks: Promise<void>[] = [];
67+
const isTS = (ext: string) => ['.ts', '.tsx', '.mts'].includes(ext);
68+
69+
function removeFile(file: string) {
70+
const relativePath = path.relative(srcPath, file);
71+
72+
// helper function to remove from both CJS and ESM paths
73+
const removeFromBuildPaths = (targetPath: string) => {
74+
if (hasCJS) {
75+
const cjsTarget = path.resolve(cjsPath, targetPath);
76+
if (fse.existsSync(cjsTarget)) {
77+
tasks.push(fse.remove(cjsTarget));
78+
}
79+
}
80+
81+
if (hasESM) {
82+
const esmTarget = path.resolve(esmPath, targetPath);
83+
if (fse.existsSync(esmTarget)) {
84+
tasks.push(fse.remove(esmTarget));
85+
}
86+
}
87+
};
88+
89+
if (isDir) {
90+
// for directories, remove directly from both CJS and ESM paths
91+
removeFromBuildPaths(relativePath);
92+
} else {
93+
// for files, handle extension conversion
94+
const dirName = path.dirname(relativePath);
95+
const fileName = path.basename(relativePath);
96+
const ext = path.extname(fileName);
97+
98+
const buildFileName =
99+
// in case file is ts group then we need to unlink the js file
100+
// but for dts files we do not convert to js
101+
isTS(ext) && !fileName.endsWith('.d.ts')
102+
? fileName.replace(ext, '.js')
103+
: fileName;
104+
105+
removeFromBuildPaths(path.join(dirName, buildFileName));
106+
}
107+
}
108+
109+
if (Array.isArray(files)) {
110+
files.forEach(removeFile);
111+
} else {
112+
removeFile(files);
113+
}
114+
115+
await Promise.all(tasks);
116+
}
117+
51118
async function postbuild(getBuildTime: ReturnType<typeof createTimer>) {
52119
const { root, srcPath, buildPath, lib } = getConfig();
53120

src/core/watch/worker.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { parentPort, isMainThread } from 'node:worker_threads';
2-
import { globSync } from 'fast-glob';
32
import { log, createTimer, createFileHash } from '@/utils';
4-
import { getConfig, initConfig } from '@/config';
3+
import { initConfig } from '@/config';
54
import build from '@/core/build';
6-
import runPostbuild from '@/core/postbuild';
5+
import runPostbuild, { unlinkFilesFormBuild } from '@/core/postbuild';
76
import type { CliProps } from '@/types';
87

98
const fileHashes = new Map<string, string>();
@@ -18,17 +17,19 @@ const actionOnWatch = async (
1817
) => {
1918
// init config on first run to prevent empty config
2019
await initConfig(cliProps);
21-
const config = getConfig();
2220

2321
// handle file hash management
2422
if (event === 'unlink') {
2523
fileHashes.delete(path);
24+
await unlinkFilesFormBuild([path]);
2625
} else if (event === 'unlinkDir') {
27-
globSync(`${path}/**/*`, {
28-
ignore: config.ignore,
29-
}).forEach(file => {
30-
fileHashes.delete(file);
31-
});
26+
// iterate through fileHashes to find files that were in the deleted directory
27+
for (const [filePath] of Array.from(fileHashes.entries())) {
28+
if (filePath.startsWith(path + '/')) {
29+
fileHashes.delete(filePath);
30+
}
31+
}
32+
await unlinkFilesFormBuild(path, true);
3233
}
3334

3435
async function runBuildProcess() {

0 commit comments

Comments
 (0)