Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion e2e/cases/output/clean-dist-path/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs';
import { join } from 'node:path';
import { build, proxyConsole } from '@e2e/helper';
import { build, dev, proxyConsole } from '@e2e/helper';
import { expect, test } from '@playwright/test';
import fse from 'fs-extra';

Expand All @@ -16,9 +16,39 @@ test('should clean dist path by default', async () => {
});

expect(fs.existsSync(testDistFile)).toBeFalsy();
});

test('should not clean dist path in dev mode when writeToDisk is false', async () => {
await fse.outputFile(testDistFile, `{ "test": 1 }`);

await dev({
cwd,
rsbuildConfig: {
dev: {
writeToDisk: false,
},
},
});

expect(fs.existsSync(testDistFile)).toBeTruthy();
fs.rmSync(testDistFile, { force: true });
});

test('should clean dist path in dev mode when writeToDisk is true', async () => {
await fse.outputFile(testDistFile, `{ "test": 1 }`);

await dev({
cwd,
rsbuildConfig: {
dev: {
writeToDisk: true,
},
},
});

expect(fs.existsSync(testDistFile)).toBeFalsy();
});

test('should not clean dist path if it is outside root', async () => {
const { logs, restore } = proxyConsole();
const testOutsideFile = join(cwd, '../node_modules/test.json');
Expand Down
18 changes: 15 additions & 3 deletions packages/core/src/plugins/cleanOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,21 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({

const getPathInfo = (
environment: EnvironmentContext,
isDev?: boolean,
): PathInfo | undefined => {
const { rootPath } = api.context;
const { config, distPath } = environment;
const { enable, keep } = normalizeCleanDistPath(
config.output.cleanDistPath,
);

// only enable cleanDistPath when the dist path is a subdir of root path
if (enable === 'auto') {
// If no files are written to disk, we don't need to clean the output
if (isDev && !config.dev.writeToDisk) {
return undefined;
}

// only clean when the dist path is a subdir of root path
if (isStrictSubdir(rootPath, distPath)) {
return {
path: distPath,
Expand Down Expand Up @@ -105,6 +111,7 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({

const cleanAll = async (params: {
environments: Record<string, EnvironmentContext>;
isDev?: boolean;
}) => {
// dedupe environments by distPath
const environments = Object.values(params.environments).reduce<
Expand All @@ -117,7 +124,9 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({
}, []);

const pathInfos: PathInfo[] = [
...environments.map(getPathInfo),
...environments.map((environment) =>
getPathInfo(environment, params.isDev),
),
getRsbuildOutputPath(),
].filter((pathInfo): pathInfo is PathInfo => !!pathInfo);

Expand All @@ -132,6 +141,9 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({
await cleanAll({ environments });
}
});
api.onBeforeStartDevServer(cleanAll);

api.onBeforeStartDevServer(async ({ environments }) => {
await cleanAll({ environments, isDev: true });
});
},
});
7 changes: 4 additions & 3 deletions website/docs/en/config/output/clean-dist-path.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ type CleanDistPath = boolean | 'auto' | CleanDistPathObject;

- **Default:** `'auto'`

Whether to clean up all files under the output directory before the build starts (the output directory defaults to `dist`).
Whether to clean up all files under the output directory before the build starts, the output directory is the value of [output.distPath.root](/config/output/dist-path).

## Default behavior

The default value of `output.cleanDistPath` is `'auto'`. If the output directory is a subdir of the project root path, Rsbuild will automatically clean all files under the output directory.
The default value of `output.cleanDistPath` is `'auto'`:

When [output.distPath.root](/config/output/dist-path) is an external directory, or equals to the project root directory, `cleanDistPath` is not enabled by default, to avoid accidentally deleting files from other directories.
- In development mode, if the value of [dev.writeToDisk](/config/dev/write-to-disk) is `false`, Rsbuild will not perform cleanup.
- In any mode, if [output.distPath.root](/config/output/dist-path) is an external directory or equals to the project root directory, Rsbuild will not perform cleanup to avoid accidentally deleting files from other directories.

```js
export default {
Expand Down
7 changes: 4 additions & 3 deletions website/docs/zh/config/output/clean-dist-path.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ type CleanDistPath = boolean | 'auto' | CleanDistPathObject;

- **默认值:** `'auto'`

是否在构建开始前清理产物目录下的所有文件(产物目录默认为 `dist`)
是否在构建开始前清理产物目录下的所有文件,产物目录为 [output.distPath.root](/config/output/dist-path) 的值

## 默认行为

`output.cleanDistPath` 的默认值为 `'auto'`。如果产物目录是项目根路径的子目录,Rsbuild 会自动清空产物目录下的文件。
`output.cleanDistPath` 的默认值为 `'auto'`

当 [output.distPath.root](/config/output/dist-path) 为外部目录,或等于项目根目录时,`cleanDistPath` 不会默认开启,这是为了避免误删其他目录的文件。
- 在开发模式下,如果 [dev.writeToDisk](/config/dev/write-to-disk) 的值为 `false`,则 Rsbuild 不会执行清理。
- 在任意模式下,如果 [output.distPath.root](/config/output/dist-path) 为外部目录,或等于项目根目录时,Rsbuild 不会执行清理,这是为了避免误删其他目录的文件。

```js
export default {
Expand Down