Skip to content

Commit

Permalink
feat: support multi serverCompiler
Browse files Browse the repository at this point in the history
  • Loading branch information
XXXMrG committed Feb 20, 2025
1 parent 9a3ba5d commit 4e7ea94
Show file tree
Hide file tree
Showing 15 changed files with 286 additions and 167 deletions.
3 changes: 3 additions & 0 deletions examples/multi-dev-server/ice.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import { defineConfig } from '@ice/app';
export default defineConfig(() => ({
ssr: true,
publicPath: '/web1/',
devPublicPath: '/web1/',
define: {
APP_NAME: JSON.stringify('app-1'),
},
environments: {
web2: {
// fixme: 这里的 publicPath 在 dev 阶段也生效了,这是不符合预期的
publicPath: '/web2/',
outputDir: 'build-web2',
devPublicPath: '/web2/',
define: {
APP_NAME: JSON.stringify('app-2'),
},
Expand Down
15 changes: 15 additions & 0 deletions examples/multi-dev-server/src/pages/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function AboutPage() {
return (
<div>
<h1>About</h1>
<p>This is the about page</p>
<p>
APP_NAME:{' '}
{
// @ts-expect-error
APP_NAME
}
</p>
</div>
);
}
5 changes: 4 additions & 1 deletion examples/multi-dev-server/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useState, lazy } from 'react';
import { useState } from 'react';
import styles from './index.module.css';
import logo from '@/assets/logo.png';

// @ts-expect-error
console.log(APP_NAME);

export default function IndexPage() {
const [count, setCount] = useState(1);
const updateCount = () => setCount((c) => c + 1);
Expand Down
62 changes: 46 additions & 16 deletions packages/ice/src/bundler/config/middlewares.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import type { Compiler } from '@rspack/core';
import type { Compiler, MultiCompiler } from '@rspack/core';
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
import type { TaskConfig } from 'build-scripts';
import type { RenderMode } from '@ice/runtime';
import type { Config } from '@ice/shared-config/types';
import type webpack from '@ice/bundles/compiled/webpack/index.js';
import webpackDevMiddleware from '@ice/bundles/compiled/webpack-dev-middleware/index.js';
import createMockMiddleware from '../../middlewares/mock/createMiddleware.js';
import createRenderMiddleware from '../../middlewares/renderMiddleware.js';
import createDataLoaderMiddleware from '../../middlewares/dataLoaderMiddleware.js';
import type { UserConfig } from '../../types/userConfig.js';
import type RouteManifest from '../../utils/routeManifest.js';
import type { GetAppConfig } from '../../types/plugin.js';

export type ICECompiler = Compiler | MultiCompiler | webpack.Compiler | webpack.MultiCompiler;

interface SetupOptions {
userConfig: UserConfig;
taskConfig: TaskConfig<Config>;
Expand All @@ -19,18 +23,25 @@ interface SetupOptions {
mock: boolean;
rootDir: string;
dataLoaderCompiler?: Compiler;
compiler?: ICECompiler;
allTaskConfigs?: TaskConfig<Config>[];
}

function setupMiddlewares(middlewares: Parameters<DevServerConfiguration['setupMiddlewares']>[0], {
userConfig,
taskConfig,
routeManifest,
getAppConfig,
excuteServerEntry,
mock,
rootDir,
dataLoaderCompiler,
}: SetupOptions) {
function setupMiddlewares(
middlewares: Parameters<DevServerConfiguration['setupMiddlewares']>[0],
{
userConfig,
taskConfig,
routeManifest,
getAppConfig,
excuteServerEntry,
mock,
rootDir,
dataLoaderCompiler,
compiler,
allTaskConfigs,
}: SetupOptions,
) {
const { ssr, ssg } = userConfig;
let renderMode: RenderMode;
// If ssr is set to true, use ssr for preview.
Expand All @@ -49,19 +60,39 @@ function setupMiddlewares(middlewares: Parameters<DevServerConfiguration['setupM
userConfig,
routeManifest,
excuteServerEntry,
allTaskConfigs,
});

// @ts-ignore property of name is exist.
const multiCompilers = (compiler as webpack.MultiCompiler).compilers;
if (Array.isArray(multiCompilers) && multiCompilers.length > 1) {
// @ts-ignore property of name is exist.
middlewares = middlewares.filter(({ name }) => name !== 'webpack-dev-middleware');

multiCompilers.forEach((comp) => {
const devMiddleware = {
name: 'webpack-dev-middleware',
// @ts-ignore property of name is exist.
middleware: webpackDevMiddleware(comp, {
publicPath: comp.options.output.publicPath,
writeToDisk: true,
}),
};

// @ts-ignore property of name is exist.
const insertIndex = middlewares.findIndex(({ name }) => name === 'express-static');
middlewares.splice(insertIndex, 0, devMiddleware);
});
}

if (dataLoaderCompiler) {
const dataLoaderMiddleware = createDataLoaderMiddleware(dataLoaderCompiler);
middlewares.unshift(dataLoaderMiddleware);
}

// @ts-ignore property of name is exist.
const insertIndex = middlewares.findIndex(({ name }) => name === 'serve-index');
middlewares.splice(
insertIndex, 0,
serverRenderMiddleware,
);
middlewares.splice(insertIndex, 0, serverRenderMiddleware);

if (mock) {
const mockMiddleware = createMockMiddleware({ rootDir, exclude: userConfig?.mock?.exclude });
Expand All @@ -70,5 +101,4 @@ function setupMiddlewares(middlewares: Parameters<DevServerConfiguration['setupM
return middlewares;
}


export default setupMiddlewares;
8 changes: 6 additions & 2 deletions packages/ice/src/bundler/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface ServerPluginOptions {
fallbackEntry?: string;
getFlattenRoutes?: () => string[];
command?: string;
name?: string;
}
export const getServerPlugin = ({
serverRunner,
Expand All @@ -61,6 +62,7 @@ export const getServerPlugin = ({
fallbackEntry,
getFlattenRoutes,
command,
name,
}: ServerPluginOptions) => {
if (serverRunner) {
return new ServerRunnerPlugin(serverRunner, ensureRoutesConfig);
Expand All @@ -75,11 +77,13 @@ export const getServerPlugin = ({
userConfig,
ensureRoutesConfig,
entryPoints: multipleServerEntry(userConfig, command)
? getEntryPoints(rootDir, getFlattenRoutes(), serverEntry) : undefined,
? getEntryPoints(rootDir, getFlattenRoutes(), serverEntry)
: undefined,
runtimeDefineVars: {
[IMPORT_META_TARGET]: JSON.stringify(target),
[IMPORT_META_RENDERER]: JSON.stringify('server'),
},
name,
});
}
};
Expand All @@ -88,6 +92,6 @@ export const getReCompilePlugin = (reCompile: (taskKey: string) => void, routeMa
return new ReCompilePlugin(reCompile, (files) => {
// Only when routes file changed.
const routeFiles = routeManifest.getRoutesFile();
return files.some((filePath) => routeFiles.some(routeFile => filePath.includes(routeFile)));
return files.some((filePath) => routeFiles.some((routeFile) => filePath.includes(routeFile)));
});
};
39 changes: 21 additions & 18 deletions packages/ice/src/bundler/rspack/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import { WEB } from '../../constant.js';
import type { BuildOptions } from '../types.js';
import formatStats from './formatStats.js';

const start = async ({
context,
rspackConfigs,
taskConfigs,
routeManifest,
compiler,
appConfig,
hooksAPI,
}: BuildOptions, dataLoaderCompiler?: Compiler) => {
const { rootDir, applyHook, commandArgs, userConfig, extendsPluginAPI: { excuteServerEntry } } = context;
const start = async (
{ context, rspackConfigs, taskConfigs, routeManifest, compiler, appConfig, hooksAPI }: BuildOptions,
dataLoaderCompiler?: Compiler,
) => {
const {
rootDir,
applyHook,
commandArgs,
userConfig,
extendsPluginAPI: { excuteServerEntry },
} = context;
const customMiddlewares = rspackConfigs[0].devServer?.setupMiddlewares;
const defaultConfig = await getDefaultServerConfig(rspackConfigs[0].devServer, commandArgs);
const webTaskConfig = taskConfigs.find(({ name }) => name === WEB);
Expand All @@ -34,14 +35,17 @@ const start = async ({
mock: commandArgs.mock,
rootDir,
dataLoaderCompiler,
compiler,
});
return customMiddlewares ? customMiddlewares(builtInMiddlewares, devServer) : builtInMiddlewares;
},
};
const routePaths = routeManifest.getFlattenRoute().sort((a, b) =>
// Sort by length, shortest path first.
a.split('/').filter(Boolean).length - b.split('/').filter(Boolean).length);
let isFirstCompile = true;
const routePaths = routeManifest.getFlattenRoute().sort(
(a, b) =>
// Sort by length, shortest path first.
a.split('/').filter(Boolean).length - b.split('/').filter(Boolean).length,
);
let isFirstCompile = true;
const urls = getUrls({
taskConfig: webTaskConfig,
appConfig,
Expand All @@ -58,15 +62,14 @@ const start = async ({
const { RspackDevServer } = await import('@ice/bundles/esm/dev-server.js');
const devServer = new RspackDevServer(devServerConfig, compiler);

compiler.hooks.done.tap('done', async stats => {
compiler.hooks.done.tap('done', async (stats) => {
const obj = stats.toJson({
all: false,
timings: true,
});
if (!stats.hasErrors()) {
obj.children?.forEach(c => {
c.time &&
logger.success(`${c.name} compiled successfully in`, c.time, 'ms');
obj.children?.forEach((c) => {
c.time && logger.success(`${c.name} compiled successfully in`, c.time, 'ms');
});
}
const { message, level } = formatStats(stats);
Expand Down
9 changes: 8 additions & 1 deletion packages/ice/src/bundler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import type { Stats as WebpackStats } from '@ice/bundles/compiled/webpack/index.
import type { AppConfig } from '@ice/runtime-kit';
import type { Configuration, MultiCompiler, MultiStats } from '@rspack/core';
import type { Context as DefaultContext, TaskConfig } from 'build-scripts';
import type { ServerCompiler, GetAppConfig, GetRoutesConfig, GetDataloaderConfig, ExtendsPluginAPI } from '../types/plugin.js';
import type {
ServerCompiler,
GetAppConfig,
GetRoutesConfig,
GetDataloaderConfig,
ExtendsPluginAPI,
} from '../types/plugin.js';
import type { UserConfig } from '../types/userConfig.js';
import type RouteManifest from '../utils/routeManifest.js';
import type ServerRunner from '../service/ServerRunner.js';
Expand Down Expand Up @@ -39,6 +45,7 @@ export interface BundlerOptions {
userConfig: UserConfig;
routeManifest: RouteManifest;
hasDataLoader: boolean;
multiEnvServerCompilers?: Map<string, ServerCompiler>;
}

export type CompileResults = {
Expand Down
9 changes: 5 additions & 4 deletions packages/ice/src/bundler/webpack/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,19 @@ async function build(

const outputPaths: string[] = [];

for (const config of webpackConfigs) {
const outputDir = config.output.path;
for (const taskConfig of taskConfigs) {
const { serverEntry: envServerEntry } = (await extendsPluginAPI.serverCompileTask.get(taskConfig.name)) || {};
const { outputDir } = taskConfig.config;
const outputPath = await getOutputPaths({
rootDir,
serverEntry,
serverEntry: envServerEntry,
outputDir,
bundleOptions: {
userConfig,
appConfig,
routeManifest,
// todo: function type publicPath
publicPath: config.output.publicPath as string,
publicPath: taskConfig.config.publicPath as string,
},
});
outputPaths.push(...outputPath);
Expand Down
Loading

0 comments on commit 4e7ea94

Please sign in to comment.