Skip to content

Commit

Permalink
feat(uni-builder): integrate modern server (#5104)
Browse files Browse the repository at this point in the history
  • Loading branch information
9aoy committed Dec 19, 2023
1 parent 08df017 commit 66fca4e
Show file tree
Hide file tree
Showing 14 changed files with 336 additions and 178 deletions.
7 changes: 7 additions & 0 deletions .changeset/serious-fans-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@modern-js/uni-builder': patch
---

feat(uni-builder): integrate modern server into startDevServer

feat(uni-builder): 将 modern server 集成到 startDevServer 中
3 changes: 3 additions & 0 deletions packages/builder/uni-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"@babel/core": "^7.23.2",
"@babel/preset-react": "^7.22.15",
"@babel/types": "^7.23.0",
"@modern-js/utils": "workspace:*",
"@modern-js/server": "workspace:*",
"@modern-js/prod-server": "workspace:*",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.10",
"@rsbuild/babel-preset": "0.2.4",
"@rsbuild/core": "0.2.4",
Expand Down
3 changes: 2 additions & 1 deletion packages/builder/uni-builder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export async function createUniBuilder(options: CreateUniBuilderOptions) {
}

export type { CreateUniBuilderOptions };
export type { BundlerChain } from '@rsbuild/shared';
export type { BundlerChain, RsbuildPlugin } from '@rsbuild/shared';
export type { BuilderConfig } from './types';
export type { StartDevServerOptions } from './shared/devServer';

export { RUNTIME_CHUNK_NAME } from './shared/constants';
28 changes: 25 additions & 3 deletions packages/builder/uni-builder/src/rspack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import type {
RsbuildPlugin,
RsbuildInstance,
} from '@rsbuild/core';
import type { RsbuildProvider } from '@rsbuild/shared';
import type { RsbuildProvider, StartServerResult } from '@rsbuild/shared';
import type {
UniBuilderRspackConfig,
CreateRspackBuilderOptions,
CreateBuilderCommonOptions,
} from '../types';
import { parseCommonConfig } from '../shared/parseCommonConfig';
import type { StartDevServerOptions } from '../shared/devServer';

export async function parseConfig(
uniBuilderConfig: UniBuilderRspackConfig,
Expand Down Expand Up @@ -53,9 +54,23 @@ export async function parseConfig(
};
}

type UniBuilderInstance = Omit<
RsbuildInstance<RsbuildProvider>,
'startDevServer'
> & {
/**
* should be used in conjunction with the upper-layer framework:
*
* missing route.json (required in modern server)
*/
startDevServer: (
options: StartDevServerOptions,
) => Promise<StartServerResult>;
};

export async function createRspackBuilder(
options: CreateRspackBuilderOptions,
): Promise<RsbuildInstance<RsbuildProvider>> {
): Promise<UniBuilderInstance> {
const { cwd = process.cwd(), config, ...rest } = options;

const { rsbuildConfig, rsbuildPlugins } = await parseConfig(config, {
Expand All @@ -70,5 +85,12 @@ export async function createRspackBuilder(

rsbuild.addPlugins(rsbuildPlugins);

return rsbuild;
return {
...rsbuild,
startDevServer: async (options: StartDevServerOptions = {}) => {
const { startDevServer } = await import('../shared/devServer');

return startDevServer(rsbuild, options, config);
},
};
}
173 changes: 173 additions & 0 deletions packages/builder/uni-builder/src/shared/devServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import {
StartDevServerOptions as RsbuildStartDevServerOptions,
getAddressUrls,
debug,
StartServerResult,
RsbuildInstance,
deepmerge,
mergeChainedOptions,
} from '@rsbuild/shared';
import type { ModernDevServerOptionsNew } from '@modern-js/server';
import { type ModernServerOptions } from '@modern-js/prod-server';
import { BuilderConfig } from '../types';

type ServerOptions = Partial<Omit<ModernDevServerOptionsNew, 'config'>> & {
config?: Partial<ModernDevServerOptionsNew['config']>;
};

const getServerOptions = (
builderConfig: BuilderConfig,
): ModernServerOptions['config'] => {
return {
output: {
path: builderConfig.output?.distPath?.root,
assetPrefix: builderConfig.output?.assetPrefix,
distPath: builderConfig.output?.distPath,
},
source: {
alias: {},
},
html: {},
tools: {
babel: {},
},
server: {},
runtime: {},
bff: {},
};
};

const getDevServerOptions = async ({
builderConfig,
serverOptions,
port,
}: {
builderConfig: BuilderConfig;
serverOptions: ServerOptions;
port: number;
}): Promise<{
config: ModernDevServerOptionsNew['config'];
devConfig: ModernDevServerOptionsNew['dev'];
}> => {
const defaultDevConfig = deepmerge(
{
hot: builderConfig.dev?.hmr ?? true,
watch: true,
client: {
port: port.toString(),
},
port,
liveReload: builderConfig.dev?.hmr ?? true,
https: builderConfig.dev?.https,
},
// merge devServerOptions from serverOptions
serverOptions.dev || {},
);

const devConfig = mergeChainedOptions({
defaults: defaultDevConfig,
options: builderConfig.tools?.devServer,
mergeFn: deepmerge,
});

const defaultConfig = getServerOptions(builderConfig);
const config = serverOptions.config
? deepmerge(defaultConfig, serverOptions.config)
: defaultConfig;

return { config, devConfig };
};

export type StartDevServerOptions = Omit<
RsbuildStartDevServerOptions,
// printURLs is not used in modern.js
'printURLs'
> & {
apiOnly?: boolean;
defaultPort?: number;
serverOptions?: ServerOptions;
};

export async function startDevServer(
rsbuild: RsbuildInstance,
options: StartDevServerOptions = {},
builderConfig: BuilderConfig,
) {
debug('create dev server');

const { ServerForRsbuild } = await import('@modern-js/server');

const rsbuildServer = await rsbuild.getServerAPIs(options);

const { serverOptions = {} } = options;

const { config, devConfig } = await getDevServerOptions({
builderConfig,
serverOptions,
port: rsbuildServer.config.port,
});

const compileMiddlewareAPI = options.apiOnly
? undefined
: await rsbuildServer.startCompile();

const server = new ServerForRsbuild({
pwd: rsbuild.context.rootPath,
...serverOptions,
rsbuild,
getMiddlewares: config =>
rsbuildServer.getMiddlewares({
compileMiddlewareAPI,
overrides: config,
}),
dev: devConfig,
config,
});

const {
config: { port, host },
} = rsbuildServer;

debug('create dev server done');

await rsbuildServer.beforeStart();

const protocol = devConfig.https ? 'https' : 'http';
const urls = getAddressUrls(protocol, port, host);

debug('listen dev server');

await server.init();

return new Promise<StartServerResult>(resolve => {
server.listen(
{
host,
port,
},
async (err?: Error) => {
if (err) {
throw err;
}

debug('listen dev server done');

await rsbuildServer.afterStart({
port,
routes: [
{
route: '/',
name: 'index',
},
],
});

resolve({
port,
urls: urls.map(item => item.url),
server,
});
},
);
});
}
Loading

0 comments on commit 66fca4e

Please sign in to comment.