Skip to content

Commit

Permalink
feat(server): should print correct urls by html entry (#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
9aoy authored Nov 11, 2023
1 parent a802111 commit b55d867
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-meals-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rsbuild/core': patch
---

feat(server): should print urls by html entry
15 changes: 13 additions & 2 deletions packages/core/src/plugins/startUrl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { join } from 'path';
import { logger, castArray, type DefaultRsbuildPlugin } from '@rsbuild/shared';
import {
logger,
castArray,
type DefaultRsbuildPlugin,
normalizeUrl,
formatRoutes,
} from '@rsbuild/shared';
import { exec } from 'child_process';
import { promisify } from 'util';

Expand Down Expand Up @@ -102,8 +108,13 @@ export function pluginStartUrl(): DefaultRsbuildPlugin {
const urls: string[] = [];

if (startUrl === true || !startUrl) {
const { entry } = api.context;
const routes = formatRoutes(entry);
const protocol = https ? 'https' : 'http';
urls.push(`${protocol}://localhost:${port}`);
// auto open the first one
urls.push(
normalizeUrl(`${protocol}://localhost:${port}/${routes[0].route}`),
);
} else {
urls.push(
...castArray(startUrl).map((item) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/server/devServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export async function startDevServer<
}
}

printServerURLs(urls, logger);
printServerURLs(urls, options.context.entry, logger);
}

debug('create dev server');
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/server/prodServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export async function startProdServer(
() => {
const urls = getAddressUrls('http', port);

printServerURLs(urls);
printServerURLs(urls, context.entry);
resolve({
port,
urls: urls.map((item) => item.url),
Expand Down
44 changes: 41 additions & 3 deletions packages/shared/src/devServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
OnBeforeStartDevServerFn,
CompilerTapFn,
DevConfig,
RsbuildEntry,
} from './types';
import { getPort } from './port';
import deepmerge from 'deepmerge';
Expand All @@ -13,14 +14,51 @@ import { logger as defaultLogger, Logger } from './logger';
import { DEFAULT_PORT, DEFAULT_DEV_HOST } from './constants';
import { createAsyncHook } from './createHook';
import type { Compiler } from '@rspack/core';
import { normalizeUrl } from './url';

/*
* format route by entry and adjust the index route to be the first
*/
export const formatRoutes = (entry: RsbuildEntry) => {
return (
Object.keys(entry)
.map((name) => ({
name,
route: name === 'index' ? '' : name,
}))
// adjust the index route to be the first
.sort((a) => (a.name === 'index' ? -1 : 1))
);
};

export function printServerURLs(
urls: Array<{ url: string; label: string }>,
entry: RsbuildEntry,
logger: Logger = defaultLogger,
) {
const message = urls
.map(({ label, url }) => ` ${`> ${label.padEnd(10)}`}${color.cyan(url)}\n`)
.join('');
const routes = formatRoutes(entry);

let message = '';
if (routes.length === 1) {
message = urls
.map(
({ label, url }) =>
` ${`> ${label.padEnd(10)}`}${color.cyan(
normalizeUrl(`${url}/${routes[0].route}`),
)}\n`,
)
.join('');
} else {
const maxNameLength = Math.max(...routes.map((r) => r.name.length));
urls.forEach(({ label, url }) => {
message += ` ${color.bold(`> ${label}`)}\n`;
routes.forEach((r) => {
message += ` ${color.yellow('○')} ${color.yellow(
r.name.padEnd(maxNameLength + 8),
)}${color.cyan(normalizeUrl(`${url}/${r.route}`))}\n`;
});
});
}

logger.log(message);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/shared/src/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { DEFAULT_DEV_HOST } from './constants';

export { urlJoin };

// remove repeat '/'
export const normalizeUrl = (url: string) => url.replace(/([^:]\/)\/+/g, '$1');

export const withPublicPath = (str: string, base: string) => {
// The use of an absolute URL without a protocol is technically legal,
// however it cannot be parsed as a URL instance.
Expand Down
122 changes: 122 additions & 0 deletions packages/shared/tests/devServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,130 @@ import {
setupServerHooks,
isClientCompiler,
mergeDevOptions,
formatRoutes,
printServerURLs,
} from '../src/devServer';

test('formatRoutes', () => {
expect(
formatRoutes({
index: 'src/index.ts',
foo: 'src/index.ts',
bar: 'src/index.ts',
}),
).toEqual([
{
name: 'index',
route: '',
},
{
name: 'foo',
route: 'foo',
},
{
name: 'bar',
route: 'bar',
},
]);

expect(
formatRoutes({
foo: 'src/index.ts',
bar: 'src/index.ts',
index: 'src/index.ts',
}),
).toEqual([
{
name: 'index',
route: '',
},
{
name: 'foo',
route: 'foo',
},
{
name: 'bar',
route: 'bar',
},
]);

expect(
formatRoutes({
foo: 'src/index.ts',
}),
).toEqual([
{
name: 'foo',
route: 'foo',
},
]);
});

test('printServerURLs', () => {
let message: string;
const logger = {
log: (msg: string) => {
message = msg;
},
};

printServerURLs(
[
{
url: 'http://localhost:8080',
label: 'local',
},
{
url: 'http://10.94.62.193:8080/',
label: 'network',
},
],
{
index: 'src/index.ts',
},
// @ts-expect-error
logger,
);

expect(message!).toMatchInlineSnapshot(`
" > local http:/localhost:8080/
> network http:/10.94.62.193:8080/
"
`);

printServerURLs(
[
{
url: 'http://localhost:8080',
label: 'local',
},
{
url: 'http://10.94.62.193:8080/',
label: 'network',
},
],
{
foo: 'src/index.ts',
bar: 'src/index.ts',
index: 'src/index.ts',
},
// @ts-expect-error
logger,
);

expect(message!).toMatchInlineSnapshot(`
" > local
○ index http:/localhost:8080/
○ foo http:/localhost:8080/foo
○ bar http:/localhost:8080/bar
> network
○ index http:/10.94.62.193:8080/
○ foo http:/10.94.62.193:8080/foo
○ bar http:/10.94.62.193:8080/bar
"
`);
});

describe('test dev server', () => {
test('should setupServerHooks correctly', () => {
const compiler = webpack({});
Expand Down
16 changes: 15 additions & 1 deletion packages/shared/tests/url.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { withPublicPath } from '../src/url';
import { withPublicPath, normalizeUrl } from '../src/url';

const PUBLIC_PATH = 'https://www.example.com/static';

it('normalizeUrl', () => {
expect(normalizeUrl('https://www.example.com/static//a')).toBe(
'https://www.example.com/static/a',
);

expect(normalizeUrl('https://www.example.com/static/a')).toBe(
'https://www.example.com/static/a',
);

expect(normalizeUrl('https://www.example.com/static/')).toBe(
'https://www.example.com/static/',
);
});

describe('withPublicPath', () => {
it('should handle relative url', () => {
expect(withPublicPath('foo/bar.js', PUBLIC_PATH)).toBe(
Expand Down

0 comments on commit b55d867

Please sign in to comment.