Skip to content
Open
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
19 changes: 18 additions & 1 deletion packages/rspack-cli/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs';
import path from 'node:path';
import util from 'node:util';
import type {
Expand Down Expand Up @@ -71,6 +72,11 @@ function createAnsiFormatter(
};
}

const hasDefaultEntry = (context: string) =>
['./src', './src.js', './src.json'].some((request) =>
fs.existsSync(path.resolve(context, request)),
Comment on lines +76 to +77
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect resolvable default entry instead of filesystem presence

The new hasDefaultEntry helper only checks whether ./src, ./src.js, or ./src.json exists on disk, but rspack still fails when ./src exists as a directory without a resolvable default module (for example, an empty src/ folder or a src/ folder containing only main.ts). In those cases rspack serve still errors on resolving ./src, yet this warning is suppressed, so the commit’s new guidance is skipped for a real missing-default-entry case.

Useful? React with 👍 / 👎.

);

export class RspackCLI {
colors: RspackCLIColors;
program: CAC;
Expand Down Expand Up @@ -207,6 +213,7 @@ export class RspackCLI {
const isServe = command === 'serve';

const internalBuildConfig = async (item: RspackOptions) => {
const configPaths = pathMap.get(item);
if (options.entry) {
item.entry = {
main: options.entry.map((x) => path.resolve(process.cwd(), x))[0], // Fix me when entry supports array
Expand Down Expand Up @@ -248,6 +255,17 @@ export class RspackCLI {
}

if (isServe) {
if (
!configPaths &&
!options.entry &&
!item.entry &&
!hasDefaultEntry(item.context ?? process.cwd())
) {
this.getLogger().warn(
"No rspack config found and default entry './src' does not exist. `rspack serve` starts a development compilation. To serve production build output, use `rspack preview [dir]`.",
);
}

const installed = (item.plugins ||= []).find(
(item) => item instanceof rspack.ProgressPlugin,
);
Expand All @@ -262,7 +280,6 @@ export class RspackCLI {
typeof cacheOptions === 'object' &&
cacheOptions.type === 'persistent'
) {
const configPaths = pathMap.get(item);
if (configPaths) {
// for persistent cache
cacheOptions.buildDependencies = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
normalizeStderr,
runWatch,
uniqueDirectoryForTest,
} from '../../utils/test-utils';

describe('serve without a config or default entry', () => {
it('suggests preview when serving build output may be intended', async () => {
const cwd = await uniqueDirectoryForTest();
const { stdout, stderr } = await runWatch(cwd, ['serve'], {
killString: /Module not found|rspack preview \[dir\]/,
});

const output = normalizeStderr(`${stdout}\n${stderr}`);
expect(output).toContain(
"No rspack config found and default entry './src' does not exist.",
);
expect(output).toContain('use `rspack preview [dir]`');
});
});
Loading