Skip to content

Commit 85b7d06

Browse files
authored
fix: validate entry correctness in bundle mode (#659)
1 parent c2bffbc commit 85b7d06

File tree

10 files changed

+84
-25
lines changed

10 files changed

+84
-25
lines changed

packages/core/src/cli/commands.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@ export function runCli(): void {
8080
await cliBuild();
8181
} catch (err) {
8282
logger.error('Failed to build.');
83-
logger.error(err);
83+
if (err instanceof AggregateError) {
84+
for (const error of err.errors) {
85+
logger.error(error);
86+
}
87+
} else {
88+
logger.error(err);
89+
}
8490
process.exit(1);
8591
}
8692
});

packages/core/src/config.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -899,22 +899,40 @@ const composeEntryConfig = async (
899899
}
900900

901901
if (bundle !== false) {
902-
let isFileEntry = false;
902+
const entryErrorReasons: string[] = [];
903903
traverseEntryQuery(entries, (entry) => {
904904
const entryAbsPath = path.isAbsolute(entry)
905905
? entry
906906
: path.resolve(root, entry);
907+
const isDirLike = path.extname(entryAbsPath) === '';
908+
const dirError = `Glob pattern ${color.cyan(`"${entry}"`)} is not supported when "bundle" is "true", considering "bundle" to "false" to use bundleless mode, or specify a file entry to bundle. See ${color.green('https://lib.rsbuild.dev/guide/basic/output-structure')} for more details.`;
909+
907910
if (fs.existsSync(entryAbsPath)) {
908911
const stats = fs.statSync(entryAbsPath);
909-
isFileEntry = stats.isFile();
912+
if (!stats.isFile()) {
913+
// Existed dir.
914+
entryErrorReasons.push(dirError);
915+
} else {
916+
// Existed file.
917+
}
918+
} else {
919+
if (isDirLike) {
920+
// Non-existed dir.
921+
entryErrorReasons.push(dirError);
922+
} else {
923+
// Non-existed file.
924+
entryErrorReasons.push(
925+
`Can't resolve the entry ${color.cyan(`"${entry}"`)} at the location ${color.cyan(`${entryAbsPath}`)}. Please ensure that the file exists.`,
926+
);
927+
}
910928
}
911929

912930
return entry;
913931
});
914932

915-
if (!isFileEntry) {
916-
throw new Error(
917-
`Glob pattern is not supported when "bundle" is "true", considering ${color.green('set "bundle" to "false"')} to use bundleless mode. See ${color.green('https://lib.rsbuild.dev/guide/basic/output-structure')} for more details.`,
933+
if (entryErrorReasons.length) {
934+
throw new AggregateError(
935+
entryErrorReasons.map((reason) => new Error(reason)),
918936
);
919937
}
920938

pnpm-lock.yaml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integration/entry/glob-bundle/rslib.config.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/integration/entry/index.test.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,34 @@ test('glob entry bundleless', async () => {
124124
`);
125125
});
126126

127-
test('glob entry bundle', async () => {
128-
const fixturePath = join(__dirname, 'glob-bundle');
127+
test('validate entry and throw errors', async () => {
128+
const fixturePath = join(__dirname, 'validate');
129129
let errMsg = '';
130130
try {
131-
await buildAndGetResults({ fixturePath });
131+
await buildAndGetResults({
132+
fixturePath,
133+
configPath: 'bundleWithGlob.config.ts',
134+
});
132135
} catch (e) {
133-
errMsg = (e as Error).message;
136+
errMsg = (e as AggregateError).errors.join('\n\n');
137+
}
138+
139+
expect(stripAnsi(errMsg)).toMatchInlineSnapshot(`
140+
"Error: Glob pattern "./src" is not supported when "bundle" is "true", considering "bundle" to "false" to use bundleless mode, or specify a file entry to bundle. See https://lib.rsbuild.dev/guide/basic/output-structure for more details.
141+
142+
Error: Glob pattern "!./src/ignored" is not supported when "bundle" is "true", considering "bundle" to "false" to use bundleless mode, or specify a file entry to bundle. See https://lib.rsbuild.dev/guide/basic/output-structure for more details."
143+
`);
144+
145+
try {
146+
await buildAndGetResults({
147+
fixturePath,
148+
configPath: 'nonExistingFile.config.ts',
149+
});
150+
} catch (e) {
151+
errMsg = (e as AggregateError).errors.join('\n\n');
134152
}
135153

136154
expect(stripAnsi(errMsg)).toMatchInlineSnapshot(
137-
`"Glob pattern is not supported when "bundle" is "true", considering set "bundle" to "false" to use bundleless mode. See https://lib.rsbuild.dev/guide/basic/output-structure for more details."`,
155+
`"Error: Can't resolve the entry "./src/main.ts" at the location <ROOT>/tests/integration/entry/validate/src/main.ts. Please ensure that the file exists."`,
138156
);
139157
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
source: {
8+
entry: {
9+
index: ['./src', '!./src/ignored'],
10+
},
11+
},
12+
}),
13+
],
14+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
source: {
8+
entry: {
9+
index: ['./src/main.ts'],
10+
},
11+
},
12+
}),
13+
],
14+
});

tests/integration/entry/glob-bundle/package.json renamed to tests/integration/entry/validate/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "entry-glob-bundle-test",
2+
"name": "entry-validate-test",
33
"version": "1.0.0",
44
"private": true,
55
"type": "module"

0 commit comments

Comments
 (0)