Skip to content

Commit

Permalink
fix: change the check rule of the rsdoctor plugin
Browse files Browse the repository at this point in the history
fix: rsdoctor plugin

fix: rsdoctor plugin

feat: support add plugins for specified environment (#2986)

Co-authored-by: neverland <[email protected]>

Update packages/core/src/plugins/rsdoctor.ts

Co-authored-by: neverland <[email protected]>

Update packages/core/src/plugins/rsdoctor.ts

Co-authored-by: neverland <[email protected]>

Update packages/core/src/plugins/rsdoctor.ts

Co-authored-by: neverland <[email protected]>

fix: modify the criteria for verifying the Rsdoctor plugin.
  • Loading branch information
easy1090 committed Jul 23, 2024
1 parent 6b3770f commit 6e9fedf
Show file tree
Hide file tree
Showing 29 changed files with 894 additions and 228 deletions.
60 changes: 60 additions & 0 deletions e2e/cases/environments/plugins/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { build, gotoPage } from '@e2e/helper';
import { expect, test } from '@playwright/test';

import { pluginReact } from '@rsbuild/plugin-react';

test('should add single environment plugin correctly', async ({ page }) => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
environments: {
web: {
output: {
filenameHash: false,
},
plugins: [pluginReact()],
},
web1: {
source: {
entry: {
main: './src/index1.ts',
},
},
output: {
assetPrefix: 'auto',
filenameHash: false,
distPath: {
root: 'dist/web1',
},
},
},
},
},
runServer: true,
});

await gotoPage(page, rsbuild);

const button = page.locator('#test');
await expect(button).toHaveText('Hello Rsbuild!');

const web1Url = new URL(`http://localhost:${rsbuild.port}/web1/main`);

await page.goto(web1Url.href);

await expect(page.locator('#test1')).toHaveText('Hello Rsbuild!');

const files = await rsbuild.unwrapOutputJSON();
const filenames = Object.keys(files);

expect(
filenames.some((filename) =>
filename.includes('dist/static/js/lib-react.js'),
),
).toBeTruthy();
expect(
filenames.some((filename) =>
filename.includes('dist/web1/static/js/lib-react.js'),
),
).toBeFalsy();
});
3 changes: 3 additions & 0 deletions e2e/cases/environments/plugins/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const App = () => <div id="test">Hello Rsbuild!</div>;

export default App;
9 changes: 9 additions & 0 deletions e2e/cases/environments/plugins/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const container = document.getElementById('root');
if (container) {
const root = createRoot(container);
root.render(React.createElement(App));
}
5 changes: 5 additions & 0 deletions e2e/cases/environments/plugins/src/index1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
document.getElementById('root').innerHTML = `
<div>
<div id="test1">Hello Rsbuild!</div>
</div>
`;
18 changes: 10 additions & 8 deletions packages/compat/webpack/src/webpackConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ async function modifyWebpackChain(
): Promise<RspackChain> {
logger.debug('modify webpack chain');

const [modifiedChain] = await context.hooks.modifyWebpackChain.call(
chain,
utils,
);
const [modifiedChain] =
await context.hooks.modifyWebpackChain.callInEnvironment({
environment: utils.environment.name,
args: [chain, utils],
});

if (utils.environment.config.tools?.webpackChain) {
for (const item of castArray(utils.environment.config.tools.webpackChain)) {
Expand All @@ -48,10 +49,11 @@ async function modifyWebpackConfig(
utils: ModifyWebpackConfigUtils,
): Promise<WebpackConfig> {
logger.debug('modify webpack config');
let [modifiedConfig] = await context.hooks.modifyWebpackConfig.call(
webpackConfig,
utils,
);
let [modifiedConfig] =
await context.hooks.modifyWebpackConfig.callInEnvironment({
environment: utils.environment.name,
args: [webpackConfig, utils],
});

if (utils.environment.config.tools?.webpack) {
modifiedConfig = reduceConfigsWithContext({
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,9 @@ export const getRsbuildInspectConfig = ({
for (const [name, config] of Object.entries(environments)) {
const debugConfig = {
...config,
pluginNames,
pluginNames: pluginManager
.getPlugins({ environment: name })
.map((p) => p.name),
};
rawEnvironmentConfigs.push({
name,
Expand Down
21 changes: 7 additions & 14 deletions packages/core/src/configChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import RspackChain from 'rspack-chain';
import { castArray, isPlainObject } from './helpers';
import { logger } from './logger';
import type {
CreateAsyncHook,
ModifyBundlerChainFn,
InternalContext,
ModifyBundlerChainUtils,
RsbuildConfig,
RsbuildContext,
RsbuildEntry,
Rspack,
RspackConfig,
Expand All @@ -19,22 +16,18 @@ export function getBundlerChain(): RspackChain {
}

export async function modifyBundlerChain(
context: RsbuildContext & {
hooks: {
modifyBundlerChain: CreateAsyncHook<ModifyBundlerChainFn>;
};
config: Readonly<RsbuildConfig>;
},
context: InternalContext,
utils: ModifyBundlerChainUtils,
): Promise<RspackChain> {
logger.debug('modify bundler chain');

const bundlerChain = getBundlerChain();

const [modifiedBundlerChain] = await context.hooks.modifyBundlerChain.call(
bundlerChain,
utils,
);
const [modifiedBundlerChain] =
await context.hooks.modifyBundlerChain.callInEnvironment({
environment: utils.environment.name,
args: [bundlerChain, utils],
});

if (utils.environment.config.tools?.bundlerChain) {
for (const item of castArray(utils.environment.config.tools.bundlerChain)) {
Expand Down
32 changes: 25 additions & 7 deletions packages/core/src/createRsbuild.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext } from './createContext';
import { pick } from './helpers';
import { getPluginAPI } from './initPlugins';
import { initPluginAPI } from './initPlugins';
import { initRsbuildConfig } from './internal';
import { logger } from './logger';
import { setCssExtractPlugin } from './pluginHelper';
Expand Down Expand Up @@ -37,8 +37,11 @@ async function applyDefaultPlugins(
),
import('./plugins/asset').then(({ pluginAsset }) => pluginAsset()),
import('./plugins/html').then(({ pluginHtml }) =>
pluginHtml(async (...args) => {
const result = await context.hooks.modifyHTMLTags.call(...args);
pluginHtml((environment: string) => async (...args) => {
const result = await context.hooks.modifyHTMLTags.callInEnvironment({
environment,
args,
});
return result[0];
}),
),
Expand Down Expand Up @@ -110,8 +113,9 @@ export async function createRsbuild(
rsbuildConfig.provider ? 'webpack' : 'rspack',
);

const pluginAPI = getPluginAPI({ context, pluginManager });
context.pluginAPI = pluginAPI;
const getPluginAPI = initPluginAPI({ context, pluginManager });
context.getPluginAPI = getPluginAPI;
const globalPluginAPI = getPluginAPI();

logger.debug('add default plugins');
await applyDefaultPlugins(pluginManager, context);
Expand Down Expand Up @@ -140,7 +144,7 @@ export async function createRsbuild(
'removePlugins',
'isPluginExists',
]),
...pick(pluginAPI, [
...pick(globalPluginAPI, [
'onBeforeBuild',
'onBeforeCreateCompiler',
'onBeforeStartDevServer',
Expand All @@ -164,13 +168,27 @@ export async function createRsbuild(
'startDevServer',
]),
preview,
context: pluginAPI.context,
context: globalPluginAPI.context,
};

if (rsbuildConfig.plugins) {
const plugins = await Promise.all(rsbuildConfig.plugins);
rsbuild.addPlugins(plugins);
}

// Register environment plugin
if (rsbuildConfig.environments) {
await Promise.all(
Object.entries(rsbuildConfig.environments).map(async ([name, config]) => {
if (config.plugins) {
const plugins = await Promise.all(config.plugins);
rsbuild.addPlugins(plugins, {
environment: name,
});
}
}),
);
}

return rsbuild;
}
110 changes: 96 additions & 14 deletions packages/core/src/initHooks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { isFunction } from './helpers';
import { isPluginMatchEnvironment } from './pluginManager';
import type {
AsyncHook,
EnvironmentAsyncHook,
HookDescriptor,
ModifyBundlerChainFn,
ModifyEnvironmentConfigFn,
Expand All @@ -22,6 +24,84 @@ import type {
OnExitFn,
} from './types';

export function createEnvironmentAsyncHook<
Callback extends (...args: any[]) => any,
>(): EnvironmentAsyncHook<Callback> {
type Hook = {
environment?: string;
handler: Callback;
};
const preGroup: Hook[] = [];
const postGroup: Hook[] = [];
const defaultGroup: Hook[] = [];

const tapEnvironment = ({
environment,
handler: cb,
}: {
environment?: string;
handler: Callback | HookDescriptor<Callback>;
}) => {
if (isFunction(cb)) {
defaultGroup.push({
environment,
handler: cb,
});
} else if (cb.order === 'pre') {
preGroup.push({
environment,
handler: cb.handler,
});
} else if (cb.order === 'post') {
postGroup.push({
environment,
handler: cb.handler,
});
} else {
defaultGroup.push({
environment,
handler: cb.handler,
});
}
};

const callInEnvironment = async ({
environment,
args: params,
}: {
environment?: string;
args: Parameters<Callback>;
}) => {
const callbacks = [...preGroup, ...defaultGroup, ...postGroup];

for (const callback of callbacks) {
// If this callback is not a global callback, the environment info should match
if (
callback.environment &&
environment &&
!isPluginMatchEnvironment(callback.environment, environment)
) {
continue;
}

const result = await callback.handler(...params);

if (result !== undefined) {
params[0] = result;
}
}

return params;
};

return {
tapEnvironment,
tap: (handler: Callback | HookDescriptor<Callback>) =>
tapEnvironment({ handler }),
callInEnvironment,
};
}

export function createAsyncHook<
Callback extends (...args: any[]) => any,
>(): AsyncHook<Callback> {
Expand All @@ -41,8 +121,7 @@ export function createAsyncHook<
}
};

const call = async (...args: Parameters<Callback>) => {
const params = args.slice(0) as Parameters<Callback>;
const call = async (...params: Parameters<Callback>) => {
const callbacks = [...preGroup, ...defaultGroup, ...postGroup];

for (const callback of callbacks) {
Expand All @@ -63,6 +142,7 @@ export function createAsyncHook<
}

export function initHooks(): {
/** The following hooks are global hooks */
onExit: AsyncHook<OnExitFn>;
onAfterBuild: AsyncHook<OnAfterBuildFn>;
onBeforeBuild: AsyncHook<OnBeforeBuildFn>;
Expand All @@ -74,13 +154,14 @@ export function initHooks(): {
onBeforeStartProdServer: AsyncHook<OnBeforeStartProdServerFn>;
onAfterCreateCompiler: AsyncHook<OnAfterCreateCompilerFn>;
onBeforeCreateCompiler: AsyncHook<OnBeforeCreateCompilerFn>;
modifyHTMLTags: AsyncHook<ModifyHTMLTagsFn>;
modifyRspackConfig: AsyncHook<ModifyRspackConfigFn>;
modifyBundlerChain: AsyncHook<ModifyBundlerChainFn>;
modifyWebpackChain: AsyncHook<ModifyWebpackChainFn>;
modifyWebpackConfig: AsyncHook<ModifyWebpackConfigFn>;
/** The following hooks are related to the environment */
modifyHTMLTags: EnvironmentAsyncHook<ModifyHTMLTagsFn>;
modifyRspackConfig: EnvironmentAsyncHook<ModifyRspackConfigFn>;
modifyBundlerChain: EnvironmentAsyncHook<ModifyBundlerChainFn>;
modifyWebpackChain: EnvironmentAsyncHook<ModifyWebpackChainFn>;
modifyWebpackConfig: EnvironmentAsyncHook<ModifyWebpackConfigFn>;
modifyRsbuildConfig: AsyncHook<ModifyRsbuildConfigFn>;
modifyEnvironmentConfig: AsyncHook<ModifyEnvironmentConfigFn>;
modifyEnvironmentConfig: EnvironmentAsyncHook<ModifyEnvironmentConfigFn>;
} {
return {
onExit: createAsyncHook<OnExitFn>(),
Expand All @@ -94,13 +175,14 @@ export function initHooks(): {
onBeforeStartProdServer: createAsyncHook<OnBeforeStartProdServerFn>(),
onAfterCreateCompiler: createAsyncHook<OnAfterCreateCompilerFn>(),
onBeforeCreateCompiler: createAsyncHook<OnBeforeCreateCompilerFn>(),
modifyHTMLTags: createAsyncHook<ModifyHTMLTagsFn>(),
modifyRspackConfig: createAsyncHook<ModifyRspackConfigFn>(),
modifyBundlerChain: createAsyncHook<ModifyBundlerChainFn>(),
modifyWebpackChain: createAsyncHook<ModifyWebpackChainFn>(),
modifyWebpackConfig: createAsyncHook<ModifyWebpackConfigFn>(),
modifyHTMLTags: createEnvironmentAsyncHook<ModifyHTMLTagsFn>(),
modifyRspackConfig: createEnvironmentAsyncHook<ModifyRspackConfigFn>(),
modifyBundlerChain: createEnvironmentAsyncHook<ModifyBundlerChainFn>(),
modifyWebpackChain: createEnvironmentAsyncHook<ModifyWebpackChainFn>(),
modifyWebpackConfig: createEnvironmentAsyncHook<ModifyWebpackConfigFn>(),
modifyRsbuildConfig: createAsyncHook<ModifyRsbuildConfigFn>(),
modifyEnvironmentConfig: createAsyncHook<ModifyEnvironmentConfigFn>(),
modifyEnvironmentConfig:
createEnvironmentAsyncHook<ModifyEnvironmentConfigFn>(),
};
}

Expand Down
Loading

0 comments on commit 6e9fedf

Please sign in to comment.