diff --git a/.changeset/serious-fans-poke.md b/.changeset/serious-fans-poke.md new file mode 100644 index 00000000000..03f714e7790 --- /dev/null +++ b/.changeset/serious-fans-poke.md @@ -0,0 +1,7 @@ +--- +'@modern-js/uni-builder': patch +--- + +feat(uni-builder): integrate modern server into startDevServer + +feat(uni-builder): 将 modern server 集成到 startDevServer 中 diff --git a/packages/builder/uni-builder/package.json b/packages/builder/uni-builder/package.json index e50427c4e03..8ffe3ba072b 100644 --- a/packages/builder/uni-builder/package.json +++ b/packages/builder/uni-builder/package.json @@ -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", diff --git a/packages/builder/uni-builder/src/index.ts b/packages/builder/uni-builder/src/index.ts index 65bcd5f377c..4f63fc1f269 100644 --- a/packages/builder/uni-builder/src/index.ts +++ b/packages/builder/uni-builder/src/index.ts @@ -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'; diff --git a/packages/builder/uni-builder/src/rspack/index.ts b/packages/builder/uni-builder/src/rspack/index.ts index 909d30509c9..d57928a93fa 100644 --- a/packages/builder/uni-builder/src/rspack/index.ts +++ b/packages/builder/uni-builder/src/rspack/index.ts @@ -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, @@ -53,9 +54,23 @@ export async function parseConfig( }; } +type UniBuilderInstance = Omit< + RsbuildInstance, + 'startDevServer' +> & { + /** + * should be used in conjunction with the upper-layer framework: + * + * missing route.json (required in modern server) + */ + startDevServer: ( + options: StartDevServerOptions, + ) => Promise; +}; + export async function createRspackBuilder( options: CreateRspackBuilderOptions, -): Promise> { +): Promise { const { cwd = process.cwd(), config, ...rest } = options; const { rsbuildConfig, rsbuildPlugins } = await parseConfig(config, { @@ -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); + }, + }; } diff --git a/packages/builder/uni-builder/src/shared/devServer.ts b/packages/builder/uni-builder/src/shared/devServer.ts new file mode 100644 index 00000000000..26516fc92ed --- /dev/null +++ b/packages/builder/uni-builder/src/shared/devServer.ts @@ -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> & { + config?: Partial; +}; + +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(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, + }); + }, + ); + }); +} diff --git a/packages/builder/uni-builder/src/shared/parseCommonConfig.ts b/packages/builder/uni-builder/src/shared/parseCommonConfig.ts index d909732a039..88e870e3369 100644 --- a/packages/builder/uni-builder/src/shared/parseCommonConfig.ts +++ b/packages/builder/uni-builder/src/shared/parseCommonConfig.ts @@ -1,4 +1,3 @@ -/* eslint-disable max-lines */ /* eslint-disable complexity */ import { deepmerge, @@ -6,8 +5,6 @@ import { CSS_MODULES_REGEX, isProd, ServerConfig, - logger, - color, RsbuildTarget, OverrideBrowserslist, getBrowserslist, @@ -18,10 +15,9 @@ import { type RsbuildConfig, } from '@rsbuild/core'; import type { + CreateBuilderCommonOptions, UniBuilderRspackConfig, UniBuilderWebpackConfig, - DevServerHttpsOptions, - CreateBuilderCommonOptions, } from '../types'; import { pluginRem } from '@rsbuild/plugin-rem'; import { pluginPug } from '@rsbuild/plugin-pug'; @@ -40,6 +36,7 @@ import { pluginCheckSyntax } from '@rsbuild/plugin-check-syntax'; import { pluginCssMinimizer } from '@rsbuild/plugin-css-minimizer'; import { pluginPostcssLegacy } from './plugins/postcssLegacy'; import { pluginDevtool } from './plugins/devtools'; +import { pluginEmitRouteFile } from './plugins/emitRouteFile'; const GLOBAL_CSS_REGEX = /\.global\.\w+$/; @@ -51,40 +48,6 @@ export const isLooseCssModules = (path: string) => { return !GLOBAL_CSS_REGEX.test(path); }; -const genHttpsOptions = async ( - userOptions: DevServerHttpsOptions, - cwd: string, -): Promise<{ - key: string; - cert: string; -}> => { - const httpsOptions: { key?: string; cert?: string } = - typeof userOptions === 'boolean' ? {} : userOptions; - - if (!httpsOptions.key || !httpsOptions.cert) { - let devcertPath: string; - - try { - devcertPath = require.resolve('devcert', { paths: [cwd, __dirname] }); - } catch (err) { - const command = color.bold(color.yellow(`npm add devcert@1.2.2 -D`)); - logger.error( - `You have enabled "dev.https" option, but the "devcert" package is not installed.`, - ); - logger.error( - `Please run ${command} to install manually, otherwise the https can not work.`, - ); - throw new Error('[https] "devcert" is not found.'); - } - - const devcert = require(devcertPath); - const selfsign = await devcert.certificateFor(['localhost']); - return selfsign; - } - - return httpsOptions as { key: string; cert: string }; -}; - function removeUndefinedKey(obj: { [key: string]: any }) { Object.keys(obj).forEach(key => { if (obj[key] === undefined) { @@ -144,11 +107,6 @@ export async function parseCommonConfig( const rsbuildConfig = deepmerge({}, uniBuilderConfig); const { dev = {}, html = {}, output = {}, tools = {} } = rsbuildConfig; - // enable progress bar by default - if (dev.progressBar === undefined) { - dev.progressBar = true; - } - if (output.cssModuleLocalIdentName) { output.cssModules ||= {}; output.cssModules.localIdentName = output.cssModuleLocalIdentName; @@ -242,48 +200,22 @@ export async function parseCommonConfig( delete html.templateParametersByEntries; } + // more dev & server config will compat in modern-js/server + + // enable progress bar by default + if (dev.progressBar === undefined) { + dev.progressBar = true; + } + + dev.writeToDisk ??= (file: string) => !file.includes('.hot-update.'); + const server: ServerConfig = isProd() - ? { - publicDir: false, - } + ? {} : { - https: - tools.devServer?.https || dev.https - ? await genHttpsOptions( - (tools.devServer?.https || dev.https)!, - cwd!, - ) - : undefined, port: dev.port, host: dev.host, - compress: tools.devServer?.compress, - headers: tools.devServer?.headers, - historyApiFallback: tools.devServer?.historyApiFallback, - proxy: tools.devServer?.proxy, - publicDir: false, }; - dev.client = tools.devServer?.client; - dev.writeToDisk = tools.devServer?.devMiddleware?.writeToDisk ?? true; - - if (tools.devServer?.hot === false) { - dev.hmr = false; - } - - if (tools.devServer?.before?.length || tools.devServer?.after?.length) { - dev.setupMiddlewares = [ - ...(tools.devServer?.setupMiddlewares || []), - middlewares => { - // the order: devServer.before => setupMiddlewares.unshift => internal middlewares => setupMiddlewares.push => devServer.after. - middlewares.unshift(...(tools.devServer?.before || [])); - - middlewares.push(...(tools.devServer?.after || [])); - }, - ]; - } else if (tools.devServer?.setupMiddlewares) { - dev.setupMiddlewares = tools.devServer?.setupMiddlewares; - } - delete tools.devServer; delete dev.https; delete dev.port; @@ -306,6 +238,7 @@ export async function parseCommonConfig( pluginDevtool({ disableSourceMap: uniBuilderConfig.output?.disableSourceMap, }), + pluginEmitRouteFile(), ]; const checkSyntaxOptions = uniBuilderConfig.security?.checkSyntax; diff --git a/packages/builder/uni-builder/src/shared/plugins/emitRouteFile.ts b/packages/builder/uni-builder/src/shared/plugins/emitRouteFile.ts new file mode 100644 index 00000000000..551b1a12d04 --- /dev/null +++ b/packages/builder/uni-builder/src/shared/plugins/emitRouteFile.ts @@ -0,0 +1,34 @@ +import { join } from 'path'; +import { type RsbuildPlugin, isFileExists } from '@rsbuild/shared'; + +/** + * generate a basic route.json for modern.js server + */ +export const pluginEmitRouteFile = (): RsbuildPlugin => ({ + name: 'uni-builder:emit-route-file', + + setup(api) { + api.onBeforeStartDevServer(async () => { + const { fs, ROUTE_SPEC_FILE } = await import('@modern-js/utils'); + const routeFilePath = join(api.context.distPath, ROUTE_SPEC_FILE); + const htmlPaths = api.getHTMLPaths(); + + const routesInfo = Object.entries(htmlPaths).map( + ([entryName, filename], index) => ({ + urlPath: index === 0 ? '/' : `/${entryName}`, + entryName, + entryPath: filename, + isSPA: true, + }), + ); + + // if the framework has already generate a route.json, do nothing + if (!(await isFileExists(routeFilePath)) && routesInfo.length) { + await fs.outputFile( + routeFilePath, + JSON.stringify({ routes: routesInfo }, null, 2), + ); + } + }); + }, +}); diff --git a/packages/builder/uni-builder/src/webpack/index.ts b/packages/builder/uni-builder/src/webpack/index.ts index ef110012320..bb37e1e414f 100644 --- a/packages/builder/uni-builder/src/webpack/index.ts +++ b/packages/builder/uni-builder/src/webpack/index.ts @@ -4,6 +4,7 @@ import { type RsbuildPlugin, type RsbuildInstance, } from '@rsbuild/core'; +import type { StartServerResult } from '@rsbuild/shared'; import type { UniBuilderWebpackConfig, CreateWebpackBuilderOptions, @@ -13,6 +14,7 @@ import { parseCommonConfig } from '../shared/parseCommonConfig'; import { pluginModuleScopes } from './plugins/moduleScopes'; import { pluginBabel } from './plugins/babel'; import { pluginReact } from './plugins/react'; +import type { StartDevServerOptions } from '../shared/devServer'; export async function parseConfig( uniBuilderConfig: UniBuilderWebpackConfig, @@ -75,9 +77,15 @@ export async function parseConfig( }; } +type UniBuilderWebpackInstance = Omit & { + startDevServer: ( + options: StartDevServerOptions, + ) => Promise; +}; + export async function createWebpackBuilder( options: CreateWebpackBuilderOptions, -): Promise { +): Promise { const { cwd = process.cwd(), config, ...rest } = options; const { rsbuildConfig, rsbuildPlugins } = await parseConfig(config, { @@ -98,5 +106,12 @@ export async function createWebpackBuilder( pluginModuleScopes(options.config.source?.moduleScopes), ]); - return rsbuild; + return { + ...rsbuild, + startDevServer: async (options: StartDevServerOptions = {}) => { + const { startDevServer } = await import('../shared/devServer'); + + return startDevServer(rsbuild, options, config); + }, + }; } diff --git a/packages/builder/uni-builder/tests/__snapshots__/parseConfig.test.ts.snap b/packages/builder/uni-builder/tests/__snapshots__/parseConfig.test.ts.snap index 34786f8c82f..207e9c78084 100644 --- a/packages/builder/uni-builder/tests/__snapshots__/parseConfig.test.ts.snap +++ b/packages/builder/uni-builder/tests/__snapshots__/parseConfig.test.ts.snap @@ -3,9 +3,8 @@ exports[`parseCommonConfig > dev.xxx 1`] = ` { "dev": { - "hmr": false, "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -28,18 +27,8 @@ exports[`parseCommonConfig > dev.xxx 1`] = ` ], }, "server": { - "compress": false, - "headers": { - "X-Custom-Foo": "bar", - }, - "historyApiFallback": true, "host": "xxx.xxx", - "https": { - "cert": "xxx", - "key": "xxxx", - }, "port": 8081, - "publicDir": false, }, "tools": {}, } @@ -49,7 +38,7 @@ exports[`parseCommonConfig > dev.xxx 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -71,9 +60,7 @@ exports[`parseCommonConfig > dev.xxx 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, "tools": {}, } `; @@ -82,7 +69,7 @@ exports[`parseCommonConfig > html.faviconByEntries 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "favicon": [Function], @@ -105,9 +92,7 @@ exports[`parseCommonConfig > html.faviconByEntries 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -115,7 +100,7 @@ exports[`parseCommonConfig > html.faviconByEntries 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "favicon": [ @@ -141,9 +126,7 @@ exports[`parseCommonConfig > html.faviconByEntries 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -151,7 +134,7 @@ exports[`parseCommonConfig > html.faviconByEntries 3`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "inject": [Function], @@ -174,9 +157,7 @@ exports[`parseCommonConfig > html.faviconByEntries 3`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -184,7 +165,7 @@ exports[`parseCommonConfig > html.faviconByEntries 4`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "inject": [ @@ -210,9 +191,7 @@ exports[`parseCommonConfig > html.faviconByEntries 4`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -220,7 +199,7 @@ exports[`parseCommonConfig > html.metaByEntries 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "meta": [Function], @@ -243,9 +222,7 @@ exports[`parseCommonConfig > html.metaByEntries 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -253,7 +230,7 @@ exports[`parseCommonConfig > html.metaByEntries 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "meta": [ @@ -283,9 +260,7 @@ exports[`parseCommonConfig > html.metaByEntries 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -293,7 +268,7 @@ exports[`parseCommonConfig > html.templateByEntries 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -316,9 +291,7 @@ exports[`parseCommonConfig > html.templateByEntries 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -326,7 +299,7 @@ exports[`parseCommonConfig > html.templateByEntries 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -352,9 +325,7 @@ exports[`parseCommonConfig > html.templateByEntries 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -362,7 +333,7 @@ exports[`parseCommonConfig > html.templateParametersByEntries 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -385,9 +356,7 @@ exports[`parseCommonConfig > html.templateParametersByEntries 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -395,7 +364,7 @@ exports[`parseCommonConfig > html.templateParametersByEntries 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -423,9 +392,7 @@ exports[`parseCommonConfig > html.templateParametersByEntries 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -433,7 +400,7 @@ exports[`parseCommonConfig > html.titleByEntries 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -458,9 +425,7 @@ exports[`parseCommonConfig > html.titleByEntries 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -468,7 +433,7 @@ exports[`parseCommonConfig > html.titleByEntries 2`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -493,9 +458,7 @@ exports[`parseCommonConfig > html.titleByEntries 2`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -503,7 +466,7 @@ exports[`parseCommonConfig > output.cssModuleLocalIdentName 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -528,9 +491,7 @@ exports[`parseCommonConfig > output.cssModuleLocalIdentName 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -538,7 +499,7 @@ exports[`parseCommonConfig > output.disableCssModuleExtension 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -564,9 +525,7 @@ exports[`parseCommonConfig > output.disableCssModuleExtension 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -574,7 +533,7 @@ exports[`parseCommonConfig > output.enableInlineScripts 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -597,9 +556,7 @@ exports[`parseCommonConfig > output.enableInlineScripts 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; @@ -607,7 +564,7 @@ exports[`parseCommonConfig > output.enableInlineStyles 1`] = ` { "dev": { "progressBar": true, - "writeToDisk": true, + "writeToDisk": [Function], }, "html": { "outputStructure": "nested", @@ -630,8 +587,6 @@ exports[`parseCommonConfig > output.enableInlineStyles 1`] = ` "web", ], }, - "server": { - "publicDir": false, - }, + "server": {}, } `; diff --git a/packages/server/server/src/index.ts b/packages/server/server/src/index.ts index 035f58152b4..06177d1cc70 100644 --- a/packages/server/server/src/index.ts +++ b/packages/server/server/src/index.ts @@ -2,10 +2,13 @@ import { DevServer as Server, DevServerForRsbuild as ServerForRsbuild, } from './server'; -import type { ModernDevServerOptions } from './types'; +import type { + ModernDevServerOptions, + ModernDevServerOptionsNew, +} from './types'; export { Server, ServerForRsbuild }; -export type { ModernDevServerOptions }; +export type { ModernDevServerOptions, ModernDevServerOptionsNew }; // TODO: it seems not used in any pkgs? export default (options: ModernDevServerOptions): Promise => { diff --git a/packages/server/server/src/server/devServer.ts b/packages/server/server/src/server/devServer.ts index 10e145a2a07..76f3273c970 100644 --- a/packages/server/server/src/server/devServer.ts +++ b/packages/server/server/src/server/devServer.ts @@ -101,7 +101,7 @@ export class ModernDevServer extends ModernServer { } private getDevOptions(options: ModernDevServerOptionsNew) { - const devOptions = typeof options.dev === 'boolean' ? {} : options.dev; + const devOptions = options.dev; const defaultOptions = getDefaultDevOptions(); return deepMerge(defaultOptions, devOptions); } diff --git a/packages/server/server/src/types.ts b/packages/server/server/src/types.ts index a4f99bb423e..6b7eb2a0b49 100644 --- a/packages/server/server/src/types.ts +++ b/packages/server/server/src/types.ts @@ -61,7 +61,7 @@ export type ExtraOptions = { export type ModernDevServerOptions = ModernServerOptions & ExtraOptions; export type ExtraOptionsNew = { - dev: boolean | Partial; + dev: Partial; useWorkerSSR?: boolean; rsbuild: RsbuildInstance; getMiddlewares: ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b745061bca..d609618554b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -747,6 +747,15 @@ importers: '@babel/types': specifier: ^7.23.0 version: 7.23.6 + '@modern-js/prod-server': + specifier: workspace:* + version: link:../../server/prod-server + '@modern-js/server': + specifier: workspace:* + version: link:../../server/server + '@modern-js/utils': + specifier: workspace:* + version: link:../../toolkit/utils '@pmmmwh/react-refresh-webpack-plugin': specifier: 0.5.10 version: 0.5.10(react-refresh@0.14.0)(webpack@5.89.0) diff --git a/tests/e2e/builder/scripts/shared.ts b/tests/e2e/builder/scripts/shared.ts index 6455f3a34b9..af3c49b69c2 100644 --- a/tests/e2e/builder/scripts/shared.ts +++ b/tests/e2e/builder/scripts/shared.ts @@ -2,14 +2,18 @@ import { URL } from 'url'; import assert from 'assert'; import { join } from 'path'; import fs from '@modern-js/utils/fs-extra'; -import type { CreateBuilderOptions } from '@modern-js/builder'; import type { BuilderConfig } from '@modern-js/builder-webpack-provider'; import type { BuilderConfig as RspackBuilderConfig } from '@modern-js/builder-rspack-provider'; import type { BuilderConfig as UniBuilderConfig, CreateUniBuilderOptions, + StartDevServerOptions, } from '@modern-js/uni-builder'; -import { StartDevServerOptions } from '@modern-js/builder-shared'; + +type CreateBuilderOptions = Omit< + CreateUniBuilderOptions, + 'bundlerType' | 'config' +>; export const getHrefByEntryName = (entryName: string, port: number) => { const baseUrl = new URL(`http://localhost:${port}`); @@ -47,7 +51,7 @@ async function getRspackBuilderProvider(builderConfig: RspackBuilderConfig) { const noop = () => {}; export const createUniBuilder = async ( - builderOptions: CreateUniBuilderOptions, + builderOptions: CreateBuilderOptions, builderConfig: UniBuilderConfig = {}, ) => { const { createUniBuilder } = await import('@modern-js/uni-builder'); @@ -143,18 +147,17 @@ export async function dev({ ...options }: CreateBuilderOptions & { builderConfig?: BuilderType extends 'webpack' - ? BuilderConfig - : RspackBuilderConfig; + ? UniBuilderConfig<'webpack'> + : UniBuilderConfig<'rspack'>; serverOptions?: StartDevServerOptions['serverOptions']; }) { process.env.NODE_ENV = 'development'; - // @ts-expect-error updateConfigForTest(builderConfig); - const builder = await createBuilder(options, builderConfig); + const builder = await createUniBuilder(options, builderConfig); + return builder.startDevServer({ - printURLs: false, serverOptions, }); }