Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: init devServer #405

Merged
merged 9 commits into from
Nov 8, 2023
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
4 changes: 3 additions & 1 deletion e2e/cases/dev/history-api-fallback.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ test('should provide history api fallback correctly', async ({ page }) => {
rsbuildConfig: {
tools: {
devServer: {
historyApiFallback: true,
historyApiFallback: {
index: '/main.html',
},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@rsbuild/plugin-vue2-jsx": "workspace:*",
"@rsbuild/shared": "workspace:*",
"@rsbuild/webpack": "workspace:*",
"@types/connect": "^3.4.37",
"@types/connect": "3.4.35",
"@types/lodash": "^4.14.200",
"@types/node": "^16",
"@types/react": "^18",
Expand Down
1 change: 0 additions & 1 deletion packages/compat/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"dependencies": {
"@babel/core": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@modern-js/server": "0.0.0-next-20231103131234",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.10",
"@rsbuild/babel-preset": "workspace:*",
"@rsbuild/core": "workspace:*",
Expand Down
6 changes: 2 additions & 4 deletions packages/compat/webpack/src/core/devMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import webpackDevMiddleware from '@rsbuild/shared/webpack-dev-middleware';
import type { Compiler, MultiCompiler } from 'webpack';
import type { ModernDevServerOptions } from '@modern-js/server';
import type { DevMiddleware } from '@rsbuild/core/server';
import { setupServerHooks, isClientCompiler } from '@rsbuild/shared';
import { IncomingMessage, ServerResponse } from 'http';

type DevMiddlewareOptions = ModernDevServerOptions['devMiddleware'];

const applyHMREntry = (
compiler: Compiler | MultiCompiler,
clientPath: string,
Expand Down Expand Up @@ -49,7 +47,7 @@ const setupHooks = (

export const getDevMiddleware: (
compiler: Compiler | MultiCompiler,
) => NonNullable<DevMiddlewareOptions> = (compiler) => (options) => {
) => NonNullable<DevMiddleware> = (compiler) => (options) => {
const { hmrClientPath, callbacks, ...restOptions } = options;

hmrClientPath && applyHMREntry(compiler, hmrClientPath);
Expand Down
8 changes: 3 additions & 5 deletions packages/compat/webpack/src/core/startDevServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ import { createCompiler } from './createCompiler';
import { initConfigs, InitConfigsOptions } from './initConfigs';
import type { Compiler, MultiCompiler } from 'webpack';
import { getDevMiddleware } from './devMiddleware';
import { createDevServer as createServer } from '@rsbuild/core/server';

export async function createDevServer(
options: InitConfigsOptions,
port: number,
serverOptions: Exclude<StartDevServerOptions['serverOptions'], undefined>,
customCompiler?: Compiler | MultiCompiler,
) {
const { Server } = await import('@modern-js/server');

let compiler: Compiler | MultiCompiler;
if (customCompiler) {
compiler = customCompiler;
Expand All @@ -31,18 +30,17 @@ export async function createDevServer(
debug('create dev server');

const rsbuildConfig = options.context.config;
const { config, devConfig } = await getDevServerOptions({
const { devConfig } = await getDevServerOptions({
rsbuildConfig,
serverOptions,
port,
});

const server = new Server({
const server = await createServer({
pwd: options.context.rootPath,
devMiddleware: getDevMiddleware(compiler),
...serverOptions,
dev: devConfig,
config,
});

debug('create dev server done');
Expand Down
25 changes: 23 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./server": {
"types": "./dist/server/index.d.ts",
"default": "./dist/server/index.js"
},
"./hmr-client": {
"types": "./dist/server/dev-middleware/hmr-client/index.d.ts",
"default": "./dist/server/dev-middleware/hmr-client/index.js"
},
"./cli": {
"types": "./dist/cli/index.d.ts",
"default": "./dist/cli/index.js"
Expand All @@ -41,6 +49,12 @@
"cli": [
"./dist/cli/index.d.ts"
],
"server": [
"./dist/server/index.d.ts"
],
"hmr-client": [
"./dist/server/dev-middleware/hmr-client/index.d.ts"
],
"plugins/*": [
"./dist/plugins/*.d.ts"
],
Expand All @@ -65,9 +79,10 @@
"dev": "modern build --watch"
},
"dependencies": {
"@modern-js/server": "0.0.0-next-20231103131234",
"@rsbuild/shared": "workspace:*",
"@rspack/core": "0.3.11",
"connect": "3.7.0",
"connect-history-api-fallback": "^2.0.0",
"commander": "^10.0.1",
"core-js": "~3.32.2",
"filesize": "^8.0.7",
Expand All @@ -77,11 +92,17 @@
"lodash": "^4.17.21",
"open": "^8.4.0",
"postcss": "8.4.31",
"semver": "^7.5.4"
"semver": "^7.5.4",
"sirv": "^2.0.3",
"strip-ansi": "^6.0.1",
"ws": "^8.2.0"
},
"devDependencies": {
"@types/connect": "3.4.35",
"@types/connect-history-api-fallback": "^1.3.5",
"@types/lodash": "^4.14.200",
"@types/node": "^16",
"@types/ws": "^8.2.0",
"@types/semver": "^7.5.4",
"typescript": "^5.2.2"
},
Expand Down
8 changes: 2 additions & 6 deletions packages/core/src/rspack-provider/core/devMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import webpackDevMiddleware from '@rsbuild/shared/webpack-dev-middleware';
import type { ModernDevServerOptions } from '@modern-js/server';
import type { DevMiddleware } from '../../server';
import { setupServerHooks, isClientCompiler } from '@rsbuild/shared';

import type { Compiler, MultiCompiler } from '@rspack/core';

type DevMiddlewareOptions = ModernDevServerOptions['devMiddleware'];

function applyHMREntry(compiler: Compiler, clientPath: string) {
if (!isClientCompiler(compiler)) {
return;
Expand All @@ -20,9 +18,7 @@ function applyHMREntry(compiler: Compiler, clientPath: string) {
}

export const getDevMiddleware =
(
multiCompiler: Compiler | MultiCompiler,
): NonNullable<DevMiddlewareOptions> =>
(multiCompiler: Compiler | MultiCompiler): NonNullable<DevMiddleware> =>
(options) => {
const { hmrClientPath, callbacks, ...restOptions } = options;

Expand Down
11 changes: 5 additions & 6 deletions packages/core/src/rspack-provider/core/startDevServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { createCompiler } from './createCompiler';
import { getDevMiddleware } from './devMiddleware';
import { initConfigs, type InitConfigsOptions } from './initConfigs';
import { createDevServer as createServer } from '../../server';

type ServerOptions = Exclude<StartDevServerOptions['serverOptions'], undefined>;

Expand All @@ -18,8 +19,6 @@ export async function createDevServer(
serverOptions: ServerOptions,
customCompiler?: RspackCompiler | RspackMultiCompiler,
) {
const { Server } = await import('@modern-js/server');

let compiler: RspackCompiler | RspackMultiCompiler;
if (customCompiler) {
compiler = customCompiler;
Expand All @@ -34,18 +33,17 @@ export async function createDevServer(
debug('create dev server');

const rsbuildConfig = options.context.config;
const { config, devConfig } = await getDevServerOptions({
const { devConfig } = await getDevServerOptions({
rsbuildConfig,
serverOptions,
port,
});

const server = new Server({
const server = await createServer({
pwd: options.context.rootPath,
devMiddleware: getDevMiddleware(compiler),
...serverOptions,
dev: devConfig,
config,
});

debug('create dev server done');
Expand All @@ -70,7 +68,8 @@ export async function startDevServer(
port,
serverOptions,
compiler as unknown as RspackCompiler,
),
// TODO: update baseStartDevServer
) as any,
startDevServerOptions,
);
}
26 changes: 26 additions & 0 deletions packages/core/src/server/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { DevServerOptions } from './types';

/**
* hmr socket connect path
*/
export const HMR_SOCK_PATH = '/webpack-hmr';

export const getDefaultDevOptions = (): DevServerOptions => {
return {
client: {
path: HMR_SOCK_PATH,
// By default it is set to the port number of the dev server
port: '',
// By default it is set to "location.hostname"
host: '',
// By default it is set to "location.protocol === 'https:' ? 'wss' : 'ws'""
protocol: '',
},
https: false,
devMiddleware: { writeToDisk: true },
watch: true,
hot: true,
compress: true,
liveReload: true,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
type ParsedSearch = {
host: string;
port: string;
path: string;
protocol?: string;
};

/**
* hmr socket connect path
*/
export const HMR_SOCK_PATH = '/webpack-hmr';

export function createSocketUrl(resourceQuery: string) {
// ?host=localhost&port=8080&path=modern_js_hmr_ws
const searchParams = resourceQuery.substr(1).split('&');
const options: Record<string, string> = {};

for (const pair of searchParams) {
const ary = pair.split('=');
options[ary[0]] = decodeURIComponent(ary[1]);
}

const currentLocation = self.location;

return getSocketUrl(options as ParsedSearch, currentLocation);
}

export function formatURL({
port,
protocol,
hostname,
pathname,
}: {
port: string;
protocol: string;
hostname: string;
pathname: string;
}) {
if (window.URL) {
// eslint-disable-next-line node/prefer-global/url, node/no-unsupported-features/node-builtins
const url = new URL('http://localhost');
url.port = port;
url.hostname = hostname;
url.protocol = protocol;
url.pathname = pathname;
return url.toString();
}

// compatible with IE11
const colon = protocol.indexOf(':') === -1 ? ':' : '';
return `${protocol}${colon}//${hostname}:${port}${pathname}`;
}

function getSocketUrl(urlParts: ParsedSearch, location: Location) {
const { host, port, path, protocol } = urlParts;

return formatURL({
protocol: protocol || (location.protocol === 'https:' ? 'wss' : 'ws'),
hostname: host || location.hostname,
port: port || location.port,
pathname: path || HMR_SOCK_PATH,
});
}
Loading