hadars 0.1.22 → 0.1.23

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.
package/dist/cli.js CHANGED
@@ -872,7 +872,7 @@ var __dirname = process.cwd();
872
872
  var packageDir = pathMod.dirname(fileURLToPath(import.meta.url));
873
873
  var clientScriptPath = pathMod.resolve(packageDir, "template.html");
874
874
  var loaderPath = existsSync(pathMod.resolve(packageDir, "loader.cjs")) ? pathMod.resolve(packageDir, "loader.cjs") : pathMod.resolve(packageDir, "loader.ts");
875
- var getConfigBase = (mode) => {
875
+ var getConfigBase = (mode, isServerBuild = false) => {
876
876
  const isDev = mode === "development";
877
877
  return {
878
878
  experiments: {
@@ -971,9 +971,12 @@ var getConfigBase = (mode) => {
971
971
  };
972
972
  };
973
973
  var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
974
- const Config = getConfigBase(opts.mode);
975
974
  const { base } = opts;
976
975
  const isDev = opts.mode === "development";
976
+ const isServerBuild = Boolean(
977
+ opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
978
+ );
979
+ const Config = getConfigBase(opts.mode, isServerBuild);
977
980
  const localConfig = {
978
981
  ...Config,
979
982
  module: {
@@ -1022,12 +1025,9 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1022
1025
  if (opts.moduleRules && opts.moduleRules.length > 0) {
1023
1026
  localConfig.module.rules.push(...opts.moduleRules);
1024
1027
  }
1025
- const isServerBuild2 = Boolean(
1026
- opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
1027
- );
1028
1028
  const slimReactIndex = pathMod.resolve(packageDir, "slim-react", "index.js");
1029
1029
  const slimReactJsx = pathMod.resolve(packageDir, "slim-react", "jsx-runtime.js");
1030
- const resolveAliases = isServerBuild2 ? {
1030
+ const resolveAliases = isServerBuild ? {
1031
1031
  // Route all React imports to slim-react for SSR.
1032
1032
  react: slimReactIndex,
1033
1033
  "react/jsx-runtime": slimReactJsx,
@@ -1038,7 +1038,7 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1038
1038
  "@emotion/cache": path.resolve(process.cwd(), "node_modules", "@emotion", "cache"),
1039
1039
  "@emotion/styled": path.resolve(process.cwd(), "node_modules", "@emotion", "styled")
1040
1040
  } : void 0;
1041
- const externals = isServerBuild2 ? [
1041
+ const externals = isServerBuild ? [
1042
1042
  // react / react-dom are replaced by slim-react via alias above — not external.
1043
1043
  // emotion should be external on server builds to avoid client/browser code
1044
1044
  "@emotion/react",
@@ -1059,9 +1059,9 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1059
1059
  extensions: [".tsx", ".ts", ".js", ".jsx"],
1060
1060
  alias: resolveAliases,
1061
1061
  // for server builds prefer the package "main"/"module" fields and avoid "browser" so we don't pick browser-specific entrypoints
1062
- mainFields: isServerBuild2 ? ["main", "module"] : ["browser", "module", "main"]
1062
+ mainFields: isServerBuild ? ["main", "module"] : ["browser", "module", "main"]
1063
1063
  };
1064
- const optimization = !isServerBuild2 && !isDev ? {
1064
+ const optimization = !isServerBuild && !isDev ? {
1065
1065
  moduleIds: "deterministic",
1066
1066
  splitChunks: {
1067
1067
  chunks: "all",
@@ -1089,7 +1089,7 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1089
1089
  externals,
1090
1090
  ...optimization !== void 0 ? { optimization } : {},
1091
1091
  plugins: [
1092
- new rspack.HtmlRspackPlugin({
1092
+ !isServerBuild && new rspack.HtmlRspackPlugin({
1093
1093
  publicPath: base || "/",
1094
1094
  template: opts.htmlTemplate ? pathMod.resolve(process.cwd(), opts.htmlTemplate) : clientScriptPath,
1095
1095
  scriptLoading: "module",
@@ -1097,12 +1097,7 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1097
1097
  inject: "head",
1098
1098
  minify: opts.mode === "production"
1099
1099
  }),
1100
- // Add `async` to the emitted module script so DOMContentLoaded fires
1101
- // as soon as HTML is parsed — without waiting for the bundle to execute.
1102
- // `<script type="module" async>` is valid: it downloads in parallel and
1103
- // executes without blocking DOMContentLoaded, while retaining module
1104
- // semantics (strict mode, ES imports, etc.).
1105
- {
1100
+ !isServerBuild && {
1106
1101
  apply(compiler) {
1107
1102
  compiler.hooks.emit.tapAsync("HadarsAsyncModuleScript", (compilation, cb) => {
1108
1103
  const asset = compilation.assets["out.html"];
@@ -1121,8 +1116,8 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1121
1116
  });
1122
1117
  }
1123
1118
  },
1124
- isDev && !isServerBuild2 && new ReactRefreshPlugin(),
1125
- includeHotPlugin && isDev && new rspack.HotModuleReplacementPlugin(),
1119
+ isDev && !isServerBuild && new ReactRefreshPlugin(),
1120
+ includeHotPlugin && isDev && !isServerBuild && new rspack.HotModuleReplacementPlugin(),
1126
1121
  ...extraPlugins
1127
1122
  ],
1128
1123
  ...localConfig,
@@ -1137,7 +1132,7 @@ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
1137
1132
  // for client builds. SSR builds still need it for dynamic import() of exports.
1138
1133
  experiments: {
1139
1134
  ...localConfig.experiments || {},
1140
- outputModule: isServerBuild2
1135
+ outputModule: isServerBuild
1141
1136
  },
1142
1137
  // Prevent rspack from watching its own build output — without this the
1143
1138
  // SSR watcher writing .hadars/index.ssr.js triggers the client compiler
package/dist/ssr-watch.js CHANGED
@@ -12,7 +12,7 @@ var __dirname = process.cwd();
12
12
  var packageDir = pathMod.dirname(fileURLToPath(import.meta.url));
13
13
  var clientScriptPath = pathMod.resolve(packageDir, "template.html");
14
14
  var loaderPath = existsSync(pathMod.resolve(packageDir, "loader.cjs")) ? pathMod.resolve(packageDir, "loader.cjs") : pathMod.resolve(packageDir, "loader.ts");
15
- var getConfigBase = (mode) => {
15
+ var getConfigBase = (mode, isServerBuild = false) => {
16
16
  const isDev = mode === "development";
17
17
  return {
18
18
  experiments: {
@@ -111,9 +111,12 @@ var getConfigBase = (mode) => {
111
111
  };
112
112
  };
113
113
  var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
114
- const Config = getConfigBase(opts.mode);
115
114
  const { base: base2 } = opts;
116
115
  const isDev = opts.mode === "development";
116
+ const isServerBuild = Boolean(
117
+ opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
118
+ );
119
+ const Config = getConfigBase(opts.mode, isServerBuild);
117
120
  const localConfig = {
118
121
  ...Config,
119
122
  module: {
@@ -162,12 +165,9 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
162
165
  if (opts.moduleRules && opts.moduleRules.length > 0) {
163
166
  localConfig.module.rules.push(...opts.moduleRules);
164
167
  }
165
- const isServerBuild2 = Boolean(
166
- opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
167
- );
168
168
  const slimReactIndex = pathMod.resolve(packageDir, "slim-react", "index.js");
169
169
  const slimReactJsx = pathMod.resolve(packageDir, "slim-react", "jsx-runtime.js");
170
- const resolveAliases = isServerBuild2 ? {
170
+ const resolveAliases = isServerBuild ? {
171
171
  // Route all React imports to slim-react for SSR.
172
172
  react: slimReactIndex,
173
173
  "react/jsx-runtime": slimReactJsx,
@@ -178,7 +178,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
178
178
  "@emotion/cache": path.resolve(process.cwd(), "node_modules", "@emotion", "cache"),
179
179
  "@emotion/styled": path.resolve(process.cwd(), "node_modules", "@emotion", "styled")
180
180
  } : void 0;
181
- const externals = isServerBuild2 ? [
181
+ const externals = isServerBuild ? [
182
182
  // react / react-dom are replaced by slim-react via alias above — not external.
183
183
  // emotion should be external on server builds to avoid client/browser code
184
184
  "@emotion/react",
@@ -199,9 +199,9 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
199
199
  extensions: [".tsx", ".ts", ".js", ".jsx"],
200
200
  alias: resolveAliases,
201
201
  // for server builds prefer the package "main"/"module" fields and avoid "browser" so we don't pick browser-specific entrypoints
202
- mainFields: isServerBuild2 ? ["main", "module"] : ["browser", "module", "main"]
202
+ mainFields: isServerBuild ? ["main", "module"] : ["browser", "module", "main"]
203
203
  };
204
- const optimization = !isServerBuild2 && !isDev ? {
204
+ const optimization = !isServerBuild && !isDev ? {
205
205
  moduleIds: "deterministic",
206
206
  splitChunks: {
207
207
  chunks: "all",
@@ -229,7 +229,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
229
229
  externals,
230
230
  ...optimization !== void 0 ? { optimization } : {},
231
231
  plugins: [
232
- new rspack.HtmlRspackPlugin({
232
+ !isServerBuild && new rspack.HtmlRspackPlugin({
233
233
  publicPath: base2 || "/",
234
234
  template: opts.htmlTemplate ? pathMod.resolve(process.cwd(), opts.htmlTemplate) : clientScriptPath,
235
235
  scriptLoading: "module",
@@ -237,12 +237,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
237
237
  inject: "head",
238
238
  minify: opts.mode === "production"
239
239
  }),
240
- // Add `async` to the emitted module script so DOMContentLoaded fires
241
- // as soon as HTML is parsed — without waiting for the bundle to execute.
242
- // `<script type="module" async>` is valid: it downloads in parallel and
243
- // executes without blocking DOMContentLoaded, while retaining module
244
- // semantics (strict mode, ES imports, etc.).
245
- {
240
+ !isServerBuild && {
246
241
  apply(compiler) {
247
242
  compiler.hooks.emit.tapAsync("HadarsAsyncModuleScript", (compilation, cb) => {
248
243
  const asset = compilation.assets["out.html"];
@@ -261,8 +256,8 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
261
256
  });
262
257
  }
263
258
  },
264
- isDev && !isServerBuild2 && new ReactRefreshPlugin(),
265
- includeHotPlugin && isDev && new rspack.HotModuleReplacementPlugin(),
259
+ isDev && !isServerBuild && new ReactRefreshPlugin(),
260
+ includeHotPlugin && isDev && !isServerBuild && new rspack.HotModuleReplacementPlugin(),
266
261
  ...extraPlugins
267
262
  ],
268
263
  ...localConfig,
@@ -277,7 +272,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
277
272
  // for client builds. SSR builds still need it for dynamic import() of exports.
278
273
  experiments: {
279
274
  ...localConfig.experiments || {},
280
- outputModule: isServerBuild2
275
+ outputModule: isServerBuild
281
276
  },
282
277
  // Prevent rspack from watching its own build output — without this the
283
278
  // SSR watcher writing .hadars/index.ssr.js triggers the client compiler
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hadars",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "Minimal SSR framework for React — rspack, HMR, TypeScript, Bun/Node/Deno",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -18,7 +18,7 @@ const loaderPath = existsSync(pathMod.resolve(packageDir, 'loader.cjs'))
18
18
  ? pathMod.resolve(packageDir, 'loader.cjs')
19
19
  : pathMod.resolve(packageDir, 'loader.ts');
20
20
 
21
- const getConfigBase = (mode: "development" | "production"): Omit<Configuration, "entry" | "output" | "plugins"> => {
21
+ const getConfigBase = (mode: "development" | "production", isServerBuild = false): Omit<Configuration, "entry" | "output" | "plugins"> => {
22
22
  const isDev = mode === 'development';
23
23
  return {
24
24
  experiments: {
@@ -141,9 +141,12 @@ const buildCompilerConfig = (
141
141
  opts: EntryOptions,
142
142
  includeHotPlugin: boolean,
143
143
  ): Configuration => {
144
- const Config = getConfigBase(opts.mode);
145
144
  const { base } = opts;
146
145
  const isDev = opts.mode === 'development';
146
+ const isServerBuild = Boolean(
147
+ (opts.output && typeof opts.output === 'object' && (opts.output.library || String(opts.output.filename || '').includes('ssr')))
148
+ );
149
+ const Config = getConfigBase(opts.mode, isServerBuild);
147
150
 
148
151
  // shallow-clone base config to avoid mutating shared Config while preserving RegExp and plugin instances
149
152
  const localConfig: any = {
@@ -203,15 +206,6 @@ const buildCompilerConfig = (
203
206
  localConfig.module.rules.push(...opts.moduleRules);
204
207
  }
205
208
 
206
- // For server (SSR) builds we should avoid bundling react/react-dom so
207
- // the runtime uses the same React instance as the host. If the output
208
- // is a library/module (i.e. `opts.output.library` present or filename
209
- // contains "ssr"), treat it as a server build and mark react/react-dom
210
- // as externals and alias React imports to the project's node_modules.
211
- const isServerBuild = Boolean(
212
- (opts.output && typeof opts.output === 'object' && (opts.output.library || String(opts.output.filename || '').includes('ssr')))
213
- );
214
-
215
209
  // slim-react: the SSR-only React-compatible renderer bundled with hadars.
216
210
  // On server builds we replace the real React with slim-react so that hooks
217
211
  // get safe SSR stubs, context works, and renderToStream / Suspense are
@@ -291,7 +285,7 @@ const buildCompilerConfig = (
291
285
  externals,
292
286
  ...(optimization !== undefined ? { optimization } : {}),
293
287
  plugins: [
294
- new rspack.HtmlRspackPlugin({
288
+ !isServerBuild && new rspack.HtmlRspackPlugin({
295
289
  publicPath: base || '/',
296
290
  template: opts.htmlTemplate
297
291
  ? pathMod.resolve(process.cwd(), opts.htmlTemplate)
@@ -301,12 +295,7 @@ const buildCompilerConfig = (
301
295
  inject: 'head',
302
296
  minify: opts.mode === 'production',
303
297
  }),
304
- // Add `async` to the emitted module script so DOMContentLoaded fires
305
- // as soon as HTML is parsed — without waiting for the bundle to execute.
306
- // `<script type="module" async>` is valid: it downloads in parallel and
307
- // executes without blocking DOMContentLoaded, while retaining module
308
- // semantics (strict mode, ES imports, etc.).
309
- {
298
+ !isServerBuild && {
310
299
  apply(compiler: any) {
311
300
  compiler.hooks.emit.tapAsync('HadarsAsyncModuleScript', (compilation: any, cb: () => void) => {
312
301
  const asset = compilation.assets['out.html'];
@@ -327,7 +316,7 @@ const buildCompilerConfig = (
327
316
  },
328
317
  },
329
318
  isDev && !isServerBuild && new ReactRefreshPlugin(),
330
- includeHotPlugin && isDev && new rspack.HotModuleReplacementPlugin(),
319
+ includeHotPlugin && isDev && !isServerBuild && new rspack.HotModuleReplacementPlugin(),
331
320
  ...extraPlugins,
332
321
  ],
333
322
  ...localConfig,