@rsbuild/core 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,136 +45,6 @@ function _unsupported_iterable_to_array(o, minLen) {
45
45
  if (n === "Map" || n === "Set") return Array.from(n);
46
46
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
47
47
  }
48
- var createSocketUrl = function createSocketUrl(resourceQuery) {
49
- var searchParams = resourceQuery.substr(1).split("&");
50
- var options = {};
51
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
52
- try {
53
- for(var _iterator = searchParams[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
54
- var pair = _step.value;
55
- var ary = pair.split("=");
56
- options[ary[0]] = decodeURIComponent(ary[1]);
57
- }
58
- } catch (err) {
59
- _didIteratorError = true;
60
- _iteratorError = err;
61
- } finally{
62
- try {
63
- if (!_iteratorNormalCompletion && _iterator.return != null) {
64
- _iterator.return();
65
- }
66
- } finally{
67
- if (_didIteratorError) {
68
- throw _iteratorError;
69
- }
70
- }
71
- }
72
- var currentLocation = self.location;
73
- return getSocketUrl(options, currentLocation);
74
- };
75
- var formatURL = function formatURL(param) {
76
- var port = param.port, protocol = param.protocol, hostname = param.hostname, pathname = param.pathname;
77
- if (window.URL) {
78
- var url = new URL("http://localhost");
79
- url.port = port;
80
- url.hostname = hostname;
81
- url.protocol = protocol;
82
- url.pathname = pathname;
83
- return url.toString();
84
- }
85
- var colon = protocol.indexOf(":") === -1 ? ":" : "";
86
- return "".concat(protocol).concat(colon, "//").concat(hostname, ":").concat(port).concat(pathname);
87
- };
88
- var getSocketUrl = function getSocketUrl(urlParts, location) {
89
- var host = urlParts.host, port = urlParts.port, path = urlParts.path, protocol = urlParts.protocol;
90
- return formatURL({
91
- protocol: protocol || (location.protocol === "https:" ? "wss" : "ws"),
92
- hostname: host || location.hostname,
93
- port: port || location.port,
94
- pathname: path || HMR_SOCK_PATH
95
- });
96
- };
97
- var clearOutdatedErrors = function clearOutdatedErrors() {
98
- if (typeof console !== "undefined" && typeof console.clear === "function") {
99
- if (hasCompileErrors) {
100
- console.clear();
101
- }
102
- }
103
- };
104
- var handleSuccess = function handleSuccess() {
105
- clearOutdatedErrors();
106
- var isHotUpdate = !isFirstCompilation;
107
- isFirstCompilation = false;
108
- hasCompileErrors = false;
109
- if (isHotUpdate) {
110
- tryApplyUpdates();
111
- }
112
- };
113
- var handleWarnings = function handleWarnings(warnings) {
114
- clearOutdatedErrors();
115
- var isHotUpdate = !isFirstCompilation;
116
- isFirstCompilation = false;
117
- hasCompileErrors = false;
118
- function printWarnings() {
119
- var formatted = (0, import_format_stats.formatStatsMessages)({
120
- warnings: warnings,
121
- errors: []
122
- });
123
- if (typeof console !== "undefined" && typeof console.warn === "function") {
124
- for(var i = 0; i < formatted.warnings.length; i++){
125
- if (i === 5) {
126
- console.warn("There were more warnings in other files.\nYou can find a complete log in the terminal.");
127
- break;
128
- }
129
- console.warn(formatted.warnings[i]);
130
- }
131
- }
132
- }
133
- printWarnings();
134
- if (isHotUpdate) {
135
- tryApplyUpdates();
136
- }
137
- };
138
- var handleErrors = function handleErrors(errors) {
139
- clearOutdatedErrors();
140
- isFirstCompilation = false;
141
- hasCompileErrors = true;
142
- var formatted = (0, import_format_stats.formatStatsMessages)({
143
- errors: errors,
144
- warnings: []
145
- });
146
- if (typeof console !== "undefined" && typeof console.error === "function") {
147
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
148
- try {
149
- for(var _iterator = formatted.errors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
150
- var error = _step.value;
151
- console.error(error);
152
- }
153
- } catch (err) {
154
- _didIteratorError = true;
155
- _iteratorError = err;
156
- } finally{
157
- try {
158
- if (!_iteratorNormalCompletion && _iterator.return != null) {
159
- _iterator.return();
160
- }
161
- } finally{
162
- if (_didIteratorError) {
163
- throw _iteratorError;
164
- }
165
- }
166
- }
167
- }
168
- };
169
- var handleAvailableHash = function handleAvailableHash(hash) {
170
- mostRecentCompilationHash = hash;
171
- };
172
- var isUpdateAvailable = function isUpdateAvailable() {
173
- return mostRecentCompilationHash !== __webpack_hash__;
174
- };
175
- var canApplyUpdates = function canApplyUpdates() {
176
- return module.hot.status() === "idle";
177
- };
178
48
  var __create = Object.create;
179
49
  var __defProp = Object.defineProperty;
180
50
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -233,63 +103,6 @@ var __toESM = function(mod, isNodeMode, target) {
233
103
  var require_formatStats = __commonJS({
234
104
  "../shared/dist/formatStats.js": function(exports2, module2) {
235
105
  "use strict";
236
- var isLikelyASyntaxError = function isLikelyASyntaxError(message) {
237
- return message.includes(friendlySyntaxErrorLabel);
238
- };
239
- var formatMessage = function formatMessage(stats) {
240
- var lines = [];
241
- var message;
242
- if (typeof stats === "object") {
243
- var fileName = stats.moduleName ? "File: ".concat(stats.moduleName, "\n") : "";
244
- var mainMessage = typeof stats.formatted === "string" ? stats.formatted : stats.message;
245
- var details = stats.details ? "\nDetails: ".concat(stats.details, "\n") : "";
246
- var stack = stats.stack ? "\n".concat(stats.stack) : "";
247
- message = "".concat(fileName).concat(mainMessage).concat(details).concat(stack);
248
- } else {
249
- message = stats;
250
- }
251
- lines = message.split("\n");
252
- lines = lines.map(function(line) {
253
- var parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(line);
254
- if (!parsingError) {
255
- return line;
256
- }
257
- var _parsingError = _sliced_to_array(parsingError, 4), errorLine = _parsingError[1], errorColumn = _parsingError[2], errorMessage = _parsingError[3];
258
- return "".concat(friendlySyntaxErrorLabel, " ").concat(errorMessage, " (").concat(errorLine, ":").concat(errorColumn, ")");
259
- });
260
- message = lines.join("\n");
261
- message = message.replace(/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g, "".concat(friendlySyntaxErrorLabel, " $3 ($1:$2)\n"));
262
- lines = message.split("\n");
263
- if (lines.length > 2 && lines[1].trim() === "") {
264
- lines.splice(1, 1);
265
- }
266
- lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, "$1");
267
- if (lines[1] && lines[1].indexOf("Module not found:") !== -1) {
268
- lines[1] = lines[1].replace("Error: ", "");
269
- }
270
- lines = lines.filter(function(line, index, arr) {
271
- return index === 0 || line.trim() !== "" || line.trim() !== arr[index - 1].trim();
272
- });
273
- message = lines.join("\n");
274
- return message.trim();
275
- };
276
- var formatStatsMessages2 = function formatStatsMessages2(json) {
277
- var _a, _b, _c;
278
- var formattedErrors = (_a = json == null ? void 0 : json.errors) == null ? void 0 : _a.map(formatMessage);
279
- var formattedWarnings = (_b = json == null ? void 0 : json.warnings) == null ? void 0 : _b.map(formatMessage);
280
- var result = {
281
- errors: formattedErrors || [],
282
- warnings: formattedWarnings || [],
283
- errorTips: []
284
- };
285
- if ((_c = result.errors) == null ? void 0 : _c.some(isLikelyASyntaxError)) {
286
- result.errors = result.errors.filter(isLikelyASyntaxError);
287
- }
288
- if (result.errors.length > 1) {
289
- result.errors.length = 1;
290
- }
291
- return result;
292
- };
293
106
  var __defProp2 = Object.defineProperty;
294
107
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
295
108
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
@@ -344,12 +157,118 @@ var require_formatStats = __commonJS({
344
157
  });
345
158
  module2.exports = __toCommonJS(formatStats_exports);
346
159
  var friendlySyntaxErrorLabel = "SyntaxError:";
160
+ function isLikelyASyntaxError(message) {
161
+ return message.includes(friendlySyntaxErrorLabel);
162
+ }
163
+ function formatMessage(stats) {
164
+ var lines = [];
165
+ var message;
166
+ if (typeof stats === "object") {
167
+ var fileName = stats.moduleName ? "File: ".concat(stats.moduleName, "\n") : "";
168
+ var mainMessage = typeof stats.formatted === "string" ? stats.formatted : stats.message;
169
+ var details = stats.details ? "\nDetails: ".concat(stats.details, "\n") : "";
170
+ var stack = stats.stack ? "\n".concat(stats.stack) : "";
171
+ message = "".concat(fileName).concat(mainMessage).concat(details).concat(stack);
172
+ } else {
173
+ message = stats;
174
+ }
175
+ lines = message.split("\n");
176
+ lines = lines.map(function(line) {
177
+ var parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(line);
178
+ if (!parsingError) {
179
+ return line;
180
+ }
181
+ var _parsingError = _sliced_to_array(parsingError, 4), errorLine = _parsingError[1], errorColumn = _parsingError[2], errorMessage = _parsingError[3];
182
+ return "".concat(friendlySyntaxErrorLabel, " ").concat(errorMessage, " (").concat(errorLine, ":").concat(errorColumn, ")");
183
+ });
184
+ message = lines.join("\n");
185
+ message = message.replace(/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g, "".concat(friendlySyntaxErrorLabel, " $3 ($1:$2)\n"));
186
+ lines = message.split("\n");
187
+ if (lines.length > 2 && lines[1].trim() === "") {
188
+ lines.splice(1, 1);
189
+ }
190
+ lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, "$1");
191
+ if (lines[1] && lines[1].indexOf("Module not found:") !== -1) {
192
+ lines[1] = lines[1].replace("Error: ", "");
193
+ }
194
+ lines = lines.filter(function(line, index, arr) {
195
+ return index === 0 || line.trim() !== "" || line.trim() !== arr[index - 1].trim();
196
+ });
197
+ message = lines.join("\n");
198
+ return message.trim();
199
+ }
200
+ function formatStatsMessages2(json) {
201
+ var _a, _b, _c;
202
+ var formattedErrors = (_a = json == null ? void 0 : json.errors) == null ? void 0 : _a.map(formatMessage);
203
+ var formattedWarnings = (_b = json == null ? void 0 : json.warnings) == null ? void 0 : _b.map(formatMessage);
204
+ var result = {
205
+ errors: formattedErrors || [],
206
+ warnings: formattedWarnings || [],
207
+ errorTips: []
208
+ };
209
+ if ((_c = result.errors) == null ? void 0 : _c.some(isLikelyASyntaxError)) {
210
+ result.errors = result.errors.filter(isLikelyASyntaxError);
211
+ }
212
+ if (result.errors.length > 1) {
213
+ result.errors.length = 1;
214
+ }
215
+ return result;
216
+ }
347
217
  }
348
218
  });
349
219
  // src/client/hmr/index.ts
350
220
  var import_format_stats = __toESM(require_formatStats());
351
221
  // src/client/hmr/createSocketUrl.ts
352
222
  var HMR_SOCK_PATH = "/rsbuild-hmr";
223
+ function createSocketUrl(resourceQuery) {
224
+ var searchParams = resourceQuery.substr(1).split("&");
225
+ var options = {};
226
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
227
+ try {
228
+ for(var _iterator = searchParams[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
229
+ var pair = _step.value;
230
+ var ary = pair.split("=");
231
+ options[ary[0]] = decodeURIComponent(ary[1]);
232
+ }
233
+ } catch (err) {
234
+ _didIteratorError = true;
235
+ _iteratorError = err;
236
+ } finally{
237
+ try {
238
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
239
+ _iterator.return();
240
+ }
241
+ } finally{
242
+ if (_didIteratorError) {
243
+ throw _iteratorError;
244
+ }
245
+ }
246
+ }
247
+ var currentLocation = self.location;
248
+ return getSocketUrl(options, currentLocation);
249
+ }
250
+ function formatURL(param) {
251
+ var port = param.port, protocol = param.protocol, hostname = param.hostname, pathname = param.pathname;
252
+ if (window.URL) {
253
+ var url = new URL("http://localhost");
254
+ url.port = port;
255
+ url.hostname = hostname;
256
+ url.protocol = protocol;
257
+ url.pathname = pathname;
258
+ return url.toString();
259
+ }
260
+ var colon = protocol.indexOf(":") === -1 ? ":" : "";
261
+ return "".concat(protocol).concat(colon, "//").concat(hostname, ":").concat(port).concat(pathname);
262
+ }
263
+ function getSocketUrl(urlParts, location) {
264
+ var host = urlParts.host, port = urlParts.port, path = urlParts.path, protocol = urlParts.protocol;
265
+ return formatURL({
266
+ protocol: protocol || (location.protocol === "https:" ? "wss" : "ws"),
267
+ hostname: host || location.hostname,
268
+ port: port || location.port,
269
+ pathname: path || HMR_SOCK_PATH
270
+ });
271
+ }
353
272
  // src/client/hmr/index.ts
354
273
  var hadRuntimeError = false;
355
274
  var socketUrl = createSocketUrl(__resourceQuery);
@@ -367,6 +286,81 @@ connection.onclose = function() {
367
286
  var isFirstCompilation = true;
368
287
  var mostRecentCompilationHash = null;
369
288
  var hasCompileErrors = false;
289
+ function clearOutdatedErrors() {
290
+ if (typeof console !== "undefined" && typeof console.clear === "function") {
291
+ if (hasCompileErrors) {
292
+ console.clear();
293
+ }
294
+ }
295
+ }
296
+ function handleSuccess() {
297
+ clearOutdatedErrors();
298
+ var isHotUpdate = !isFirstCompilation;
299
+ isFirstCompilation = false;
300
+ hasCompileErrors = false;
301
+ if (isHotUpdate) {
302
+ tryApplyUpdates();
303
+ }
304
+ }
305
+ function handleWarnings(warnings) {
306
+ clearOutdatedErrors();
307
+ var isHotUpdate = !isFirstCompilation;
308
+ isFirstCompilation = false;
309
+ hasCompileErrors = false;
310
+ function printWarnings() {
311
+ var formatted = (0, import_format_stats.formatStatsMessages)({
312
+ warnings: warnings,
313
+ errors: []
314
+ });
315
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
316
+ for(var i = 0; i < formatted.warnings.length; i++){
317
+ if (i === 5) {
318
+ console.warn("There were more warnings in other files.\nYou can find a complete log in the terminal.");
319
+ break;
320
+ }
321
+ console.warn(formatted.warnings[i]);
322
+ }
323
+ }
324
+ }
325
+ printWarnings();
326
+ if (isHotUpdate) {
327
+ tryApplyUpdates();
328
+ }
329
+ }
330
+ function handleErrors(errors) {
331
+ clearOutdatedErrors();
332
+ isFirstCompilation = false;
333
+ hasCompileErrors = true;
334
+ var formatted = (0, import_format_stats.formatStatsMessages)({
335
+ errors: errors,
336
+ warnings: []
337
+ });
338
+ if (typeof console !== "undefined" && typeof console.error === "function") {
339
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
340
+ try {
341
+ for(var _iterator = formatted.errors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
342
+ var error = _step.value;
343
+ console.error(error);
344
+ }
345
+ } catch (err) {
346
+ _didIteratorError = true;
347
+ _iteratorError = err;
348
+ } finally{
349
+ try {
350
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
351
+ _iterator.return();
352
+ }
353
+ } finally{
354
+ if (_didIteratorError) {
355
+ throw _iteratorError;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ function handleAvailableHash(hash) {
362
+ mostRecentCompilationHash = hash;
363
+ }
370
364
  connection.onmessage = function(e) {
371
365
  var message = JSON.parse(e.data);
372
366
  switch(message.type){
@@ -389,6 +383,12 @@ connection.onmessage = function(e) {
389
383
  default:
390
384
  }
391
385
  };
386
+ function isUpdateAvailable() {
387
+ return mostRecentCompilationHash !== __webpack_hash__;
388
+ }
389
+ function canApplyUpdates() {
390
+ return module.hot.status() === "idle";
391
+ }
392
392
  function tryApplyUpdates() {
393
393
  if (!module.hot) {
394
394
  window.location.reload();
@@ -64,13 +64,14 @@ const calcFileSize = (len) => {
64
64
  async function printFileSizes(stats, distPath) {
65
65
  const { default: gzipSize } = await Promise.resolve().then(() => __toESM(require("@rsbuild/shared/gzip-size")));
66
66
  const formatAsset = (asset) => {
67
- const contents = import_shared.fse.readFileSync(import_path.default.join(distPath, asset.name));
67
+ const fileName = asset.name.split("?")[0];
68
+ const contents = import_shared.fse.readFileSync(import_path.default.join(distPath, fileName));
68
69
  const size = contents.length;
69
70
  const gzippedSize = gzipSize.sync(contents);
70
71
  return {
71
72
  size,
72
- folder: import_path.default.join(import_path.default.basename(distPath), import_path.default.dirname(asset.name)),
73
- name: import_path.default.basename(asset.name),
73
+ folder: import_path.default.join(import_path.default.basename(distPath), import_path.default.dirname(fileName)),
74
+ name: import_path.default.basename(fileName),
74
75
  gzippedSize,
75
76
  sizeLabel: calcFileSize(size),
76
77
  gzipSizeLabel: getAssetColor(gzippedSize)(calcFileSize(gzippedSize))
@@ -1,15 +1,17 @@
1
- import type { MetaAttrs, HtmlConfig, MetaOptions, NormalizedConfig, SharedRsbuildPluginAPI, NormalizedOutputConfig } from '@rsbuild/shared';
1
+ import type { HtmlConfig, NormalizedConfig, SharedRsbuildPluginAPI, NormalizedOutputConfig } from '@rsbuild/shared';
2
2
  import type { RsbuildPlugin } from '../types';
3
3
  export declare function getTitle(entryName: string, config: NormalizedConfig): string;
4
4
  export declare function getInject(entryName: string, config: NormalizedConfig): import("@rsbuild/shared").ScriptInject;
5
- export declare function getTemplatePath(entryName: string, config: NormalizedConfig): string;
5
+ export declare function getTemplate(entryName: string, config: NormalizedConfig, rootPath: string): Promise<{
6
+ templatePath: string;
7
+ templateContent?: string;
8
+ }>;
6
9
  export declare function getFavicon(entryName: string, config: {
7
10
  html: HtmlConfig;
8
11
  }): string;
9
- export declare const generateMetaTags: (metaOptions?: MetaOptions) => MetaAttrs[];
10
12
  export declare function getMetaTags(entryName: string, config: {
11
13
  html: HtmlConfig;
12
14
  output: NormalizedOutputConfig;
13
- }): Promise<MetaAttrs[]>;
15
+ }, templateContent?: string): import("@rsbuild/shared").MetaOptions;
14
16
  export declare const applyInjectTags: (api: SharedRsbuildPluginAPI) => void;
15
17
  export declare const pluginHtml: () => RsbuildPlugin;
@@ -29,11 +29,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var html_exports = {};
30
30
  __export(html_exports, {
31
31
  applyInjectTags: () => applyInjectTags,
32
- generateMetaTags: () => generateMetaTags,
33
32
  getFavicon: () => getFavicon,
34
33
  getInject: () => getInject,
35
34
  getMetaTags: () => getMetaTags,
36
- getTemplatePath: () => getTemplatePath,
35
+ getTemplate: () => getTemplate,
37
36
  getTitle: () => getTitle,
38
37
  pluginHtml: () => pluginHtml
39
38
  });
@@ -57,17 +56,39 @@ function getInject(entryName, config) {
57
56
  useObjectParam: true
58
57
  });
59
58
  }
60
- function getTemplatePath(entryName, config) {
59
+ const existTemplatePath = [];
60
+ async function getTemplate(entryName, config, rootPath) {
61
61
  const DEFAULT_TEMPLATE = import_path.default.resolve(
62
62
  __dirname,
63
63
  "../../static/template.html"
64
64
  );
65
- return (0, import_shared.mergeChainedOptions)({
65
+ const templatePath = (0, import_shared.mergeChainedOptions)({
66
66
  defaults: DEFAULT_TEMPLATE,
67
67
  options: config.html.template,
68
68
  utils: { entryName },
69
69
  useObjectParam: true
70
70
  });
71
+ if (templatePath === DEFAULT_TEMPLATE) {
72
+ return {
73
+ templatePath
74
+ };
75
+ }
76
+ const absolutePath = (0, import_path.isAbsolute)(templatePath) ? templatePath : import_path.default.resolve(rootPath, templatePath);
77
+ if (!existTemplatePath.includes(absolutePath)) {
78
+ if (!await (0, import_shared.isFileExists)(absolutePath)) {
79
+ throw new Error(
80
+ `Failed to resolve HTML template, please check if the file exists: ${import_shared.color.cyan(
81
+ absolutePath
82
+ )}`
83
+ );
84
+ }
85
+ existTemplatePath.push(absolutePath);
86
+ }
87
+ const templateContent = await import_shared.fse.readFile(absolutePath, "utf-8");
88
+ return {
89
+ templatePath: absolutePath,
90
+ templateContent
91
+ };
71
92
  }
72
93
  function getFavicon(entryName, config) {
73
94
  return (0, import_shared.mergeChainedOptions)({
@@ -77,26 +98,20 @@ function getFavicon(entryName, config) {
77
98
  useObjectParam: true
78
99
  });
79
100
  }
80
- const generateMetaTags = (metaOptions) => {
81
- if (!metaOptions) {
82
- return [];
83
- }
84
- return Object.keys(metaOptions).map((metaName) => {
85
- const metaTagContent = metaOptions[metaName];
86
- return typeof metaTagContent === "string" ? {
87
- name: metaName,
88
- content: metaTagContent
89
- } : metaTagContent;
90
- }).filter(Boolean);
91
- };
92
- async function getMetaTags(entryName, config) {
93
- const merged = (0, import_shared.mergeChainedOptions)({
101
+ function getMetaTags(entryName, config, templateContent) {
102
+ const metaTags = (0, import_shared.mergeChainedOptions)({
94
103
  defaults: {},
95
104
  options: config.html.meta,
96
105
  utils: { entryName },
97
106
  useObjectParam: true
98
107
  });
99
- return generateMetaTags(merged);
108
+ if (templateContent && metaTags.charset) {
109
+ const charsetRegExp = /<meta[^>]+charset=["'][^>]*>/i;
110
+ if (charsetRegExp.test(templateContent)) {
111
+ delete metaTags.charset;
112
+ }
113
+ }
114
+ return metaTags;
100
115
  }
101
116
  function getTemplateParameters(entryName, config, assetPrefix) {
102
117
  return (compilation, assets, assetTags, pluginOptions) => {
@@ -183,31 +198,36 @@ const pluginHtml = () => ({
183
198
  const chunks = getChunks(entryName, entryValue);
184
199
  const inject = getInject(entryName, config);
185
200
  const filename = htmlPaths[entryName];
186
- const template = getTemplatePath(entryName, config);
201
+ const { templatePath, templateContent } = await getTemplate(
202
+ entryName,
203
+ config,
204
+ api.context.rootPath
205
+ );
187
206
  const templateParameters = getTemplateParameters(
188
207
  entryName,
189
208
  config,
190
209
  assetPrefix
191
210
  );
211
+ const metaTags = getMetaTags(entryName, config, templateContent);
192
212
  const pluginOptions = {
213
+ meta: metaTags,
193
214
  chunks,
194
215
  inject,
195
216
  minify,
196
217
  filename,
197
- template,
218
+ template: templatePath,
198
219
  templateParameters,
199
220
  scriptLoading: config.html.scriptLoading
200
221
  };
201
222
  const htmlInfo = {};
202
223
  htmlInfoMap[filename] = htmlInfo;
224
+ if (templateContent) {
225
+ htmlInfo.templateContent = templateContent;
226
+ }
203
227
  const title = getTitle(entryName, config);
204
228
  if (title) {
205
229
  htmlInfo.title = title;
206
230
  }
207
- const metaTags = await getMetaTags(entryName, config);
208
- if (metaTags.length) {
209
- htmlInfo.meta = metaTags;
210
- }
211
231
  const favicon = getFavicon(entryName, config);
212
232
  if (favicon) {
213
233
  if ((0, import_shared.isURL)(favicon)) {
@@ -260,11 +280,10 @@ const pluginHtml = () => ({
260
280
  // Annotate the CommonJS export names for ESM import in node:
261
281
  0 && (module.exports = {
262
282
  applyInjectTags,
263
- generateMetaTags,
264
283
  getFavicon,
265
284
  getInject,
266
285
  getMetaTags,
267
- getTemplatePath,
286
+ getTemplate,
268
287
  getTitle,
269
288
  pluginHtml
270
289
  });
@@ -1,15 +1,15 @@
1
1
  import type HtmlWebpackPlugin from 'html-webpack-plugin';
2
2
  import type { Compiler } from '@rspack/core';
3
- import type { MetaAttrs } from '@rsbuild/shared';
4
3
  export type HtmlInfo = {
5
- meta?: MetaAttrs[];
6
4
  title?: string;
7
5
  favicon?: string;
6
+ templateContent?: string;
8
7
  };
9
8
  export type HtmlBasicPluginOptions = {
10
9
  info: Record<string, HtmlInfo>;
11
10
  HtmlPlugin: typeof HtmlWebpackPlugin;
12
11
  };
12
+ export declare const hasTitle: (html?: string) => boolean;
13
13
  export declare class HtmlBasicPlugin {
14
14
  readonly name: string;
15
15
  readonly options: HtmlBasicPluginOptions;
@@ -18,9 +18,11 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var HtmlBasicPlugin_exports = {};
20
20
  __export(HtmlBasicPlugin_exports, {
21
- HtmlBasicPlugin: () => HtmlBasicPlugin
21
+ HtmlBasicPlugin: () => HtmlBasicPlugin,
22
+ hasTitle: () => hasTitle
22
23
  });
23
24
  module.exports = __toCommonJS(HtmlBasicPlugin_exports);
25
+ const hasTitle = (html) => html ? /<title/i.test(html) && /<\/title/i.test(html) : false;
24
26
  class HtmlBasicPlugin {
25
27
  constructor(options) {
26
28
  this.name = "HtmlBasicPlugin";
@@ -40,19 +42,6 @@ class HtmlBasicPlugin {
40
42
  });
41
43
  }
42
44
  };
43
- const addMetaTag = (headTags, outputName) => {
44
- const { meta } = this.options.info[outputName];
45
- if (meta) {
46
- headTags.unshift(
47
- ...meta.map((attr) => ({
48
- tagName: "meta",
49
- attributes: attr,
50
- meta: {},
51
- voidTag: true
52
- }))
53
- );
54
- }
55
- };
56
45
  const addFavicon = (headTags, outputName) => {
57
46
  const { favicon } = this.options.info[outputName];
58
47
  if (favicon) {
@@ -72,8 +61,10 @@ class HtmlBasicPlugin {
72
61
  this.name,
73
62
  (data) => {
74
63
  const { headTags, outputName } = data;
75
- addTitleTag(headTags, outputName);
76
- addMetaTag(headTags, outputName);
64
+ const { templateContent } = this.options.info[outputName];
65
+ if (!hasTitle(templateContent)) {
66
+ addTitleTag(headTags, outputName);
67
+ }
77
68
  addFavicon(headTags, outputName);
78
69
  return data;
79
70
  }
@@ -83,5 +74,6 @@ class HtmlBasicPlugin {
83
74
  }
84
75
  // Annotate the CommonJS export names for ESM import in node:
85
76
  0 && (module.exports = {
86
- HtmlBasicPlugin
77
+ HtmlBasicPlugin,
78
+ hasTitle
87
79
  });
@@ -1,4 +1,4 @@
1
- import { type RspackConfig, CreateDevMiddlewareReturns, type RspackCompiler, type RspackMultiCompiler } from '@rsbuild/shared';
1
+ import { type RspackConfig, type RspackCompiler, type RspackMultiCompiler, type CreateDevMiddlewareReturns } from '@rsbuild/shared';
2
2
  import { type InitConfigsOptions } from './initConfigs';
3
3
  import type { Context } from '../../types';
4
4
  export declare function createCompiler({