@rsbuild/core 0.1.0 → 0.1.1

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.
@@ -62,7 +62,7 @@ async function init({
62
62
  }
63
63
  }
64
64
  function runCli() {
65
- import_commander.program.name("rsbuild").usage("<command> [options]").version("0.1.0");
65
+ import_commander.program.name("rsbuild").usage("<command> [options]").version("0.1.1");
66
66
  import_commander.program.command("dev").option(`--open`, "open the page in browser on startup").option(
67
67
  "-c --config <config>",
68
68
  "specify the configuration file, can be a relative or absolute path"
@@ -73,7 +73,7 @@ function runCli() {
73
73
  open: options.open
74
74
  }));
75
75
  } catch (err) {
76
- import_shared.logger.error("Failed to start dev server, please check logs.");
76
+ import_shared.logger.error("Failed to start dev server.");
77
77
  import_shared.logger.error(err);
78
78
  process.exit(1);
79
79
  }
@@ -86,7 +86,7 @@ function runCli() {
86
86
  const rsbuild = await init({ cliOptions: options });
87
87
  await (rsbuild == null ? void 0 : rsbuild.build());
88
88
  } catch (err) {
89
- import_shared.logger.error("Failed to build, please check logs.");
89
+ import_shared.logger.error("Failed to build.");
90
90
  import_shared.logger.error(err);
91
91
  process.exit(1);
92
92
  }
@@ -99,7 +99,7 @@ function runCli() {
99
99
  const rsbuild = await init({ cliOptions: options });
100
100
  await (rsbuild == null ? void 0 : rsbuild.preview());
101
101
  } catch (err) {
102
- import_shared.logger.error("Failed to start preview server, please check logs.");
102
+ import_shared.logger.error("Failed to start preview server.");
103
103
  import_shared.logger.error(err);
104
104
  process.exit(1);
105
105
  }
@@ -117,7 +117,7 @@ function runCli() {
117
117
  writeToDisk: true
118
118
  }));
119
119
  } catch (err) {
120
- import_shared.logger.error("Failed to inspect config, please check logs.");
120
+ import_shared.logger.error("Failed to inspect config.");
121
121
  import_shared.logger.error(err);
122
122
  process.exit(1);
123
123
  }
@@ -34,7 +34,7 @@ function prepareCli() {
34
34
  if (!npm_execpath || npm_execpath.includes("npx-cli.js")) {
35
35
  console.log();
36
36
  }
37
- import_rslog.logger.greet(` ${`Rsbuild v${"0.1.0"}`}
37
+ import_rslog.logger.greet(` ${`Rsbuild v${"0.1.1"}`}
38
38
  `);
39
39
  }
40
40
  // Annotate the CommonJS export names for ESM import in node:
@@ -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
+ }): Promise<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,13 @@ 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
101
  async function getMetaTags(entryName, config) {
93
- const merged = (0, import_shared.mergeChainedOptions)({
102
+ return (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);
100
108
  }
101
109
  function getTemplateParameters(entryName, config, assetPrefix) {
102
110
  return (compilation, assets, assetTags, pluginOptions) => {
@@ -183,31 +191,36 @@ const pluginHtml = () => ({
183
191
  const chunks = getChunks(entryName, entryValue);
184
192
  const inject = getInject(entryName, config);
185
193
  const filename = htmlPaths[entryName];
186
- const template = getTemplatePath(entryName, config);
194
+ const { templatePath, templateContent } = await getTemplate(
195
+ entryName,
196
+ config,
197
+ api.context.rootPath
198
+ );
187
199
  const templateParameters = getTemplateParameters(
188
200
  entryName,
189
201
  config,
190
202
  assetPrefix
191
203
  );
204
+ const metaTags = await getMetaTags(entryName, config);
192
205
  const pluginOptions = {
206
+ meta: metaTags,
193
207
  chunks,
194
208
  inject,
195
209
  minify,
196
210
  filename,
197
- template,
211
+ template: templatePath,
198
212
  templateParameters,
199
213
  scriptLoading: config.html.scriptLoading
200
214
  };
201
215
  const htmlInfo = {};
202
216
  htmlInfoMap[filename] = htmlInfo;
217
+ if (templateContent) {
218
+ htmlInfo.templateContent = templateContent;
219
+ }
203
220
  const title = getTitle(entryName, config);
204
221
  if (title) {
205
222
  htmlInfo.title = title;
206
223
  }
207
- const metaTags = await getMetaTags(entryName, config);
208
- if (metaTags.length) {
209
- htmlInfo.meta = metaTags;
210
- }
211
224
  const favicon = getFavicon(entryName, config);
212
225
  if (favicon) {
213
226
  if ((0, import_shared.isURL)(favicon)) {
@@ -260,11 +273,10 @@ const pluginHtml = () => ({
260
273
  // Annotate the CommonJS export names for ESM import in node:
261
274
  0 && (module.exports = {
262
275
  applyInjectTags,
263
- generateMetaTags,
264
276
  getFavicon,
265
277
  getInject,
266
278
  getMetaTags,
267
- getTemplatePath,
279
+ getTemplate,
268
280
  getTitle,
269
281
  pluginHtml
270
282
  });
@@ -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
  });
@@ -64,7 +64,7 @@ function createContextByConfig(options, bundlerType, sourceConfig = {}, outputCo
64
64
  entry: sourceConfig.entry || // TODO: remove sourceConfig.entries in v0.2.0
65
65
  // compat with previous config
66
66
  sourceConfig.entries || getDefaultEntry(rootPath),
67
- version: "0.1.0",
67
+ version: "0.1.1",
68
68
  target,
69
69
  rootPath,
70
70
  distPath,
@@ -92,7 +92,7 @@ const pluginSwc = () => ({
92
92
  swcConfig.env.mode = void 0;
93
93
  } else {
94
94
  swcConfig.env.mode = polyfillMode;
95
- await applyCoreJs(swcConfig, chain, rule, polyfillMode);
95
+ await applyCoreJs(swcConfig, chain, polyfillMode);
96
96
  }
97
97
  }
98
98
  rule.use(CHAIN_ID.USE.SWC).loader(builtinSwcLoaderName).options(swcConfig);
@@ -110,7 +110,7 @@ const pluginSwc = () => ({
110
110
  });
111
111
  }
112
112
  });
113
- async function applyCoreJs(swcConfig, chain, rule, polyfillMode) {
113
+ async function applyCoreJs(swcConfig, chain, polyfillMode) {
114
114
  const coreJsPath = require.resolve("core-js/package.json");
115
115
  const version = (0, import_shared.getCoreJsVersion)(coreJsPath);
116
116
  const coreJsDir = path.dirname(coreJsPath);
@@ -121,7 +121,6 @@ async function applyCoreJs(swcConfig, chain, rule, polyfillMode) {
121
121
  chain.resolve.alias.merge({
122
122
  "core-js": coreJsDir
123
123
  });
124
- rule.exclude.add(coreJsDir);
125
124
  }
126
125
  function applyTransformImport(swcConfig, pluginImport) {
127
126
  var _a, _b, _c;
@@ -21,7 +21,6 @@ __export(transition_exports, {
21
21
  pluginTransition: () => pluginTransition
22
22
  });
23
23
  module.exports = __toCommonJS(transition_exports);
24
- var import_shared = require("@rsbuild/shared");
25
24
  const pluginTransition = () => ({
26
25
  name: "rsbuild:transition",
27
26
  setup(api) {
@@ -31,9 +30,6 @@ const pluginTransition = () => ({
31
30
  chain.optimization.chunkIds("deterministic");
32
31
  }
33
32
  });
34
- api.modifyRspackConfig((config) => {
35
- (0, import_shared.setConfig)(config, "experiments.rspackFuture.newResolver", true);
36
- });
37
33
  }
38
34
  });
39
35
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,9 +1,10 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { Server } from 'http';
3
+ import type { Server } from 'http';
4
4
  import { EventEmitter } from 'events';
5
5
  import type { DevConfig, DevMiddlewareAPI, DevMiddleware as CustomDevMiddleware } from '@rsbuild/shared';
6
6
  type Options = {
7
+ publicPaths: string[];
7
8
  dev: DevConfig;
8
9
  devMiddleware?: CustomDevMiddleware;
9
10
  };
@@ -11,10 +12,12 @@ export default class DevMiddleware extends EventEmitter {
11
12
  middleware?: DevMiddlewareAPI;
12
13
  private devOptions;
13
14
  private devMiddleware?;
15
+ private publicPaths;
14
16
  private socketServer;
15
17
  constructor({
16
18
  dev,
17
- devMiddleware
19
+ devMiddleware,
20
+ publicPaths
18
21
  }: Options);
19
22
  init(app: Server): void;
20
23
  close(): void;
@@ -44,15 +44,19 @@ function getHMRClientPath(client) {
44
44
  return clientEntry;
45
45
  }
46
46
  class DevMiddleware extends import_events.EventEmitter {
47
- constructor({ dev, devMiddleware }) {
47
+ constructor({ dev, devMiddleware, publicPaths }) {
48
48
  super();
49
49
  this.devOptions = dev;
50
+ this.publicPaths = publicPaths;
50
51
  this.socketServer = new import_socketServer.default(dev);
51
52
  this.devMiddleware = devMiddleware;
52
53
  }
53
54
  init(app) {
54
55
  if (this.devMiddleware) {
55
- this.middleware = this.setupDevMiddleware(this.devMiddleware);
56
+ this.middleware = this.setupDevMiddleware(
57
+ this.devMiddleware,
58
+ this.publicPaths
59
+ );
56
60
  }
57
61
  app.on("listening", () => {
58
62
  this.socketServer.prepare(app);
@@ -66,7 +70,7 @@ class DevMiddleware extends import_events.EventEmitter {
66
70
  sockWrite(type, data) {
67
71
  this.socketServer.sockWrite(type, data);
68
72
  }
69
- setupDevMiddleware(devMiddleware) {
73
+ setupDevMiddleware(devMiddleware, publicPaths) {
70
74
  const { devOptions } = this;
71
75
  const callbacks = {
72
76
  onInvalid: () => {
@@ -80,12 +84,27 @@ class DevMiddleware extends import_events.EventEmitter {
80
84
  const enableHMR = this.devOptions.hmr;
81
85
  const middleware = devMiddleware({
82
86
  headers: devOptions.headers,
87
+ publicPath: "/",
83
88
  stats: false,
84
89
  callbacks,
85
90
  hmrClientPath: enableHMR ? getHMRClientPath(devOptions.client) : void 0,
86
91
  serverSideRender: true,
87
92
  writeToDisk: devOptions.writeToDisk
88
93
  });
89
- return middleware;
94
+ const warp = async (req, res, next) => {
95
+ const url = req.url;
96
+ const assetPrefix = url && publicPaths.find((prefix) => url.startsWith(prefix));
97
+ if (assetPrefix && assetPrefix !== "/") {
98
+ req.url = url.slice(assetPrefix.length - 1);
99
+ middleware(req, res, (...args) => {
100
+ req.url = url;
101
+ next(...args);
102
+ });
103
+ } else {
104
+ middleware(req, res, next);
105
+ }
106
+ };
107
+ warp.close = middleware.close;
108
+ return warp;
90
109
  }
91
110
  }
@@ -50,6 +50,7 @@ class RsbuildDevServer {
50
50
  this.output = options.output;
51
51
  this.devMiddleware = new import_dev_middleware.default({
52
52
  dev: this.dev,
53
+ publicPaths: options.output.publicPaths,
53
54
  devMiddleware: options.devMiddleware
54
55
  });
55
56
  }
@@ -116,7 +117,6 @@ class RsbuildDevServer {
116
117
  this.middlewares.use(
117
118
  (0, import_middlewares.getHtmlFallbackMiddleware)({
118
119
  distPath: (0, import_path.isAbsolute)(distPath) ? distPath : (0, import_path.join)(this.pwd, distPath),
119
- publicPath: this.output.publicPath,
120
120
  callback: devMiddleware.middleware,
121
121
  htmlFallback: this.dev.htmlFallback
122
122
  })
@@ -192,14 +192,14 @@ async function startDevServer(options, createDevMiddleware, {
192
192
  options,
193
193
  customCompiler
194
194
  );
195
- const publicPath = compiler.compilers ? (0, import_shared.getPublicPathFromCompiler)(compiler.compilers[0]) : (0, import_shared.getPublicPathFromCompiler)(compiler);
195
+ const publicPaths = compiler.compilers ? compiler.compilers.map(import_shared.getPublicPathFromCompiler) : [(0, import_shared.getPublicPathFromCompiler)(compiler)];
196
196
  const server = new RsbuildDevServer({
197
197
  pwd: options.context.rootPath,
198
198
  devMiddleware,
199
199
  dev: devServerConfig,
200
200
  output: {
201
201
  distPath: ((_d = (_c = rsbuildConfig.output) == null ? void 0 : _c.distPath) == null ? void 0 : _d.root) || import_shared.ROOT_DIST_DIR,
202
- publicPath
202
+ publicPaths
203
203
  }
204
204
  });
205
205
  (0, import_shared.debug)("create dev server done");
@@ -3,7 +3,6 @@ export declare const faviconFallbackMiddleware: Middleware;
3
3
  export declare const notFoundMiddleware: Middleware;
4
4
  export declare const getHtmlFallbackMiddleware: (params: {
5
5
  distPath: string;
6
- publicPath: string;
7
6
  callback?: Middleware;
8
7
  htmlFallback?: HtmlFallback;
9
8
  }) => Middleware;
@@ -48,7 +48,7 @@ const notFoundMiddleware = (_req, res, _next) => {
48
48
  res.statusCode = 404;
49
49
  res.end();
50
50
  };
51
- const getHtmlFallbackMiddleware = ({ htmlFallback, publicPath, distPath, callback }) => {
51
+ const getHtmlFallbackMiddleware = ({ htmlFallback, distPath, callback }) => {
52
52
  return (req, res, next) => {
53
53
  if (
54
54
  // Only accept GET or HEAD
@@ -68,7 +68,6 @@ const getHtmlFallbackMiddleware = ({ htmlFallback, publicPath, distPath, callbac
68
68
  }
69
69
  const rewrite = (newUrl) => {
70
70
  var _a;
71
- newUrl = (0, import_shared.urlJoin)(publicPath, newUrl);
72
71
  (_a = import_shared.debug) == null ? void 0 : _a(`Rewriting ${req.method} ${req.url} to ${newUrl}`);
73
72
  req.url = newUrl;
74
73
  if (callback) {
@@ -94,10 +93,6 @@ const getHtmlFallbackMiddleware = ({ htmlFallback, publicPath, distPath, callbac
94
93
  if (outputFileSystem.existsSync(filePath)) {
95
94
  return rewrite(newUrl);
96
95
  }
97
- } else {
98
- if (outputFileSystem.existsSync(import_path.default.join(distPath, pathname))) {
99
- return rewrite(url);
100
- }
101
96
  }
102
97
  if (htmlFallback === "index") {
103
98
  if (outputFileSystem.existsSync(import_path.default.join(distPath, "index.html"))) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsbuild/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Unleash the power of Rspack with the out-of-the-box build tool.",
5
5
  "homepage": "https://rsbuild.dev",
6
6
  "bugs": {
@@ -64,7 +64,7 @@
64
64
  "postcss": "8.4.31",
65
65
  "semver": "^7.5.4",
66
66
  "ws": "^8.2.0",
67
- "@rsbuild/shared": "0.1.0"
67
+ "@rsbuild/shared": "0.1.1"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/node": "^16",