Skip to content
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
2 changes: 1 addition & 1 deletion e2e/cases/html/combined/static/bar.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">bar</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/combined/static/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">foo</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/combined/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">text</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/inject/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</head>
<body>
<div id="test-template">text</div>
<div id="root" />
<div id="root"></div>
<%= htmlPlugin.tags.bodyTags %>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/minify/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
</head>
<body>
<div id="test-template">bar</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/template/static/bar.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">bar</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/template/static/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">foo</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/html/template/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
</head>
<body>
<div id="test-template">text</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

<body>
<div id="test-template">test</div>
<div id="root" />
<div id="root"></div>
</body>
</html>
2 changes: 1 addition & 1 deletion e2e/cases/server/reload-html/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
<title>Foo</title>
</head>
<body>
<div id="root" />
<div id="root"></div>
</body>
</html>
1 change: 1 addition & 0 deletions packages/core/src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ const getDefaultHtmlConfig = (): NormalizedHtmlConfig => ({
crossorigin: false,
outputStructure: 'flat',
scriptLoading: 'defer',
implementation: 'js',
});

const getDefaultSecurityConfig = (): NormalizedSecurityConfig => ({
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/pluginHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { requireCompiledPackage } from './helpers/vendors';
import { rspack } from './rspack';
import type { HtmlRspackPlugin } from './types';
import type { HtmlRspackPlugin, NormalizedEnvironmentConfig } from './types';

let htmlPlugin: typeof HtmlRspackPlugin;

Expand All @@ -17,7 +17,13 @@ export const setHTMLPlugin = (plugin: typeof HtmlRspackPlugin): void => {
}
};

export const getHTMLPlugin = (): typeof HtmlRspackPlugin => {
export const getHTMLPlugin = (
config?: NormalizedEnvironmentConfig,
): typeof HtmlRspackPlugin => {
if (config?.html.implementation === 'native') {
// TODO: remove type assertion
return rspack.HtmlRspackPlugin as unknown as typeof HtmlRspackPlugin;
}
if (!htmlPlugin) {
htmlPlugin = requireCompiledPackage('html-rspack-plugin');
}
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,11 @@ export const pluginHtml = (context: InternalContext): RsbuildPlugin => ({
});

const getExtraData = (entryName: string) => extraDataMap.get(entryName);
const getHTMLPlugin = () => HtmlPlugin;

chain
.plugin('rsbuild-html-plugin')
.use(RsbuildHtmlPlugin, [getExtraData]);
.use(RsbuildHtmlPlugin, [getExtraData, getHTMLPlugin]);

if (config.html) {
const { crossorigin } = config.html;
Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/plugins/resourceHints.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isRegExp } from 'node:util/types';
import { castArray } from '../helpers';
import { getHTMLPlugin } from '../pluginHelper';
import { HtmlResourceHintsPlugin } from '../rspack-plugins/resource-hints/HtmlResourceHintsPlugin';
import type {
HtmlBasicTag,
Expand Down Expand Up @@ -90,6 +91,7 @@ export const pluginResourceHints = (): RsbuildPlugin => ({
'prefetch',
HTMLCount,
isDev,
() => getHTMLPlugin(config),
]);
}

Expand All @@ -104,7 +106,13 @@ export const pluginResourceHints = (): RsbuildPlugin => ({

chain
.plugin(CHAIN_ID.PLUGIN.HTML_PRELOAD)
.use(HtmlResourceHintsPlugin, [options, 'preload', HTMLCount, isDev]);
.use(HtmlResourceHintsPlugin, [
options,
'preload',
HTMLCount,
isDev,
() => getHTMLPlugin(config),
]);
}
});
},
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/provider/rspackConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function getChainUtils(
isServer: target === 'node',
isWebWorker: target === 'web-worker',
CHAIN_ID,
HtmlPlugin: getHTMLPlugin(),
HtmlPlugin: getHTMLPlugin(environment.config),
};
}

Expand Down
11 changes: 8 additions & 3 deletions packages/core/src/rspack-plugins/RsbuildHtmlPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { color, isFunction, partition } from '../helpers';
import { addCompilationError } from '../helpers/compiler';
import { ensureAssetPrefix, isURL } from '../helpers/url';
import { logger } from '../logger';
import { getHTMLPlugin } from '../pluginHelper';
import type {
EnvironmentContext,
HtmlBasicTag,
Expand Down Expand Up @@ -245,9 +244,15 @@ export class RsbuildHtmlPlugin {

readonly getExtraData: (entryName: string) => HtmlExtraData | undefined;

constructor(getExtraData: (entryName: string) => HtmlExtraData | undefined) {
readonly getHTMLPlugin: () => typeof HtmlRspackPlugin;

constructor(
getExtraData: (entryName: string) => HtmlExtraData | undefined,
getHTMLPlugin: () => typeof HtmlRspackPlugin,
) {
this.name = 'RsbuildHtmlPlugin';
this.getExtraData = getExtraData;
this.getHTMLPlugin = getHTMLPlugin;
}

apply(compiler: Compiler): void {
Expand Down Expand Up @@ -370,7 +375,7 @@ export class RsbuildHtmlPlugin {
};

compiler.hooks.compilation.tap(this.name, (compilation: Compilation) => {
const hooks = getHTMLPlugin().getCompilationHooks(compilation);
const hooks = this.getHTMLPlugin().getCompilationHooks(compilation);

hooks.alterAssetTagGroups.tapPromise(this.name, async (data) => {
const extraData = getExtraDataByPlugin(data.plugin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import type {
} from '@rspack/core';
import { castArray, isFunction, upperFirst } from '../../helpers';
import { ensureAssetPrefix } from '../../helpers/url';
import { getHTMLPlugin } from '../../pluginHelper';
import type {
HtmlRspackPlugin,
ResourceHintsFilter,
Expand Down Expand Up @@ -242,21 +241,25 @@ export class HtmlResourceHintsPlugin implements RspackPluginInstance {

isDev: boolean;

getHTMLPlugin: () => typeof HtmlRspackPlugin;

constructor(
options: ResourceHintsOptions,
type: LinkType,
HTMLCount: number,
isDev: boolean,
getHTMLPlugin: () => typeof HtmlRspackPlugin,
) {
this.options = { ...defaultOptions, ...options };
this.type = type;
this.HTMLCount = HTMLCount;
this.isDev = isDev;
this.getHTMLPlugin = getHTMLPlugin;
}

apply(compiler: Compiler): void {
compiler.hooks.compilation.tap(this.name, (compilation) => {
const pluginHooks = getHTMLPlugin().getCompilationHooks(compilation);
const pluginHooks = this.getHTMLPlugin().getCompilationHooks(compilation);
const pluginName = `HTML${upperFirst(this.type)}Plugin`;

pluginHooks.beforeAssetTagGeneration.tap(pluginName, (data) => {
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,8 @@ export type AppIcon = {
filename?: string;
};

type HtmlImplementation = 'js' | 'native';

export interface HtmlConfig {
/**
* Configure the `<meta>` tag of the HTML.
Expand Down Expand Up @@ -1591,6 +1593,19 @@ export interface HtmlConfig {
* @default 'defer'. If `output.module` is enabled, the value is always `'module'`.
*/
scriptLoading?: ScriptLoading;
/**
* Specifies which implementation to use for generating HTML files.
*
* - `'js'` (default) - Use the JavaScript-based `html-rspack-plugin`.
* - `'native'` - Use Rspack's built-in `HtmlRspackPlugin` implemented in Rust.
*
* This option is experimental and may affect the available options in `tools.htmlPlugin`,
* since the two implementations are not fully compatible.
*
* @default 'js'
* @experimental
*/
implementation?: HtmlImplementation;
}

export type NormalizedHtmlConfig = HtmlConfig & {
Expand All @@ -1601,6 +1616,7 @@ export type NormalizedHtmlConfig = HtmlConfig & {
crossorigin: boolean | CrossOrigin;
outputStructure: OutputStructure;
scriptLoading: ScriptLoading;
implementation: HtmlImplementation;
};

export type ProgressBarConfig = {
Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/__snapshots__/builder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ exports[`should use Rspack as the default bundler > apply Rspack correctly 1`] =
},
RsbuildHtmlPlugin {
"getExtraData": [Function],
"getHTMLPlugin": [Function],
"name": "RsbuildHtmlPlugin",
},
DefinePlugin {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/tests/__snapshots__/default.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = `
},
RsbuildHtmlPlugin {
"getExtraData": [Function],
"getHTMLPlugin": [Function],
"name": "RsbuildHtmlPlugin",
},
DefinePlugin {
Expand Down Expand Up @@ -1019,6 +1020,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when prod
},
RsbuildHtmlPlugin {
"getExtraData": [Function],
"getHTMLPlugin": [Function],
"name": "RsbuildHtmlPlugin",
},
DefinePlugin {
Expand Down
9 changes: 9 additions & 0 deletions packages/core/tests/__snapshots__/environments.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports[`environment config > should normalize environment config correctly 1`]
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -179,6 +180,7 @@ exports[`environment config > should normalize environment config correctly 2`]
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -339,6 +341,7 @@ exports[`environment config > should print environment config when inspect confi
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -495,6 +498,7 @@ exports[`environment config > should print environment config when inspect confi
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -671,6 +675,7 @@ exports[`environment config > should support modify environment config by api.mo
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -827,6 +832,7 @@ exports[`environment config > should support modify environment config by api.mo
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -984,6 +990,7 @@ exports[`environment config > should support modify environment config by api.mo
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -1144,6 +1151,7 @@ exports[`environment config > should support modify single environment config by
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down Expand Up @@ -1300,6 +1308,7 @@ exports[`environment config > should support modify single environment config by
},
"html": {
"crossorigin": false,
"implementation": "js",
"inject": "head",
"meta": {
"charset": {
Expand Down
Loading
Loading