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
21 changes: 21 additions & 0 deletions e2e/cases/output/invalid-target/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { build } from '@e2e/helper';
import { expect, test } from '@playwright/test';

test('should throw error when `output.target` is invalid', async () => {
const rsbuild = await build({
cwd: __dirname,
catchBuildError: true,
rsbuildConfig: {
output: {
// @ts-expect-error test invalid target
target: 'foo',
},
},
});

expect(rsbuild.buildError?.message).toContain(
`Invalid value of output.target: "foo", valid values are:`,
);

await rsbuild.close();
});
1 change: 1 addition & 0 deletions e2e/cases/output/invalid-target/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
2 changes: 2 additions & 0 deletions e2e/scripts/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import assert from 'node:assert';
import net from 'node:net';
import { join } from 'node:path';
import { URL } from 'node:url';
import { stripVTControlCharacters as stripAnsi } from 'node:util';
import type {
CreateRsbuildOptions,
RsbuildConfig,
Expand Down Expand Up @@ -287,6 +288,7 @@ export async function build({
closeBuild = result.close;
} catch (error) {
buildError = error as Error;
buildError.message = stripAnsi(buildError.message);

if (!catchBuildError) {
throw buildError;
Expand Down
33 changes: 25 additions & 8 deletions packages/core/src/provider/initConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,31 @@ const validateRsbuildConfig = (config: NormalizedConfig) => {
);
}

if (config.environments) {
const names = Object.keys(config.environments);
const regexp = /^[\w$-]+$/;
for (const name of names) {
// ensure environment names are filesystem and property access safe
if (!regexp.test(name)) {
logger.warn(
`${color.dim('[rsbuild:config]')} Environment name "${color.yellow(name)}" contains invalid characters. Only letters, numbers, "-", "_", and "$" are allowed.`,
if (!config.environments) {
return;
}

const environmentNames = Object.keys(config.environments);
const environmentNameRegexp = /^[\w$-]+$/;
const validTargets = ['web', 'node', 'web-worker'];

for (const name of environmentNames) {
// ensure environment names are filesystem and property access safe
if (!environmentNameRegexp.test(name)) {
logger.warn(
`${color.dim('[rsbuild:config]')} Environment name "${color.yellow(name)}" contains invalid characters. Only letters, numbers, "-", "_", and "$" are allowed.`,
);
}

const outputConfig = config.environments[name].output;
if (outputConfig.target) {
if (!validTargets.includes(outputConfig.target)) {
throw new Error(
`${color.dim('[rsbuild:config]')} Invalid value of ${color.yellow(
'output.target',
)}: ${color.yellow(`"${outputConfig.target}"`)}, valid values are: ${color.yellow(
validTargets.join(', '),
)}`,
);
}
}
Expand Down
Loading