@modern-js/runtime 2.56.1 → 2.56.3-alpha.0

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.
@@ -75,11 +75,15 @@ const generateCode = async (entrypoints, appContext, config, onCollectRuntimePlu
75
75
  });
76
76
  const indexFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_FILE_NAME}`);
77
77
  import_utils.fs.outputFileSync(indexFile, indexCode, "utf8");
78
+ const ssrMode = getSSRMode(entryName, config);
78
79
  if (enableAsyncEntry) {
79
80
  const bootstrapFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_BOOTSTRAP_FILE_NAME}`);
80
81
  import_utils.fs.outputFileSync(bootstrapFile, `import('./${import_constants.INDEX_FILE_NAME}');`, "utf8");
82
+ const bootstrapServerFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_SERVER_BOOTSTRAP_FILE_NAME}`);
83
+ if (ssrMode) {
84
+ import_utils.fs.outputFileSync(bootstrapServerFile, `export const requestHandler = import('./${import_constants.SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, "utf8");
85
+ }
81
86
  }
82
- const ssrMode = getSSRMode(entryName, config);
83
87
  if (ssrMode) {
84
88
  const indexServerCode = serverTemplate.serverIndex({
85
89
  entry,
@@ -24,6 +24,7 @@ __export(constants_exports, {
24
24
  ENTRY_POINT_REGISTER_FILE_NAME: () => ENTRY_POINT_REGISTER_FILE_NAME,
25
25
  ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME: () => ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME,
26
26
  ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME: () => ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME,
27
+ ENTRY_SERVER_BOOTSTRAP_FILE_NAME: () => ENTRY_SERVER_BOOTSTRAP_FILE_NAME,
27
28
  INDEX_FILE_NAME: () => INDEX_FILE_NAME,
28
29
  SERVER_ENTRY_POINT_FILE_NAME: () => SERVER_ENTRY_POINT_FILE_NAME
29
30
  });
@@ -33,6 +34,7 @@ const ENTRY_POINT_FILE_NAME = "index.jsx";
33
34
  const SERVER_ENTRY_POINT_FILE_NAME = "index.server.jsx";
34
35
  const INDEX_FILE_NAME = "index";
35
36
  const ENTRY_BOOTSTRAP_FILE_NAME = "bootstrap.jsx";
37
+ const ENTRY_SERVER_BOOTSTRAP_FILE_NAME = "bootstrap.server.jsx";
36
38
  const ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME = "runtime-register.js";
37
39
  const ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context.js";
38
40
  const ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
@@ -44,6 +46,7 @@ const ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
44
46
  ENTRY_POINT_REGISTER_FILE_NAME,
45
47
  ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME,
46
48
  ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME,
49
+ ENTRY_SERVER_BOOTSTRAP_FILE_NAME,
47
50
  INDEX_FILE_NAME,
48
51
  SERVER_ENTRY_POINT_FILE_NAME
49
52
  });
@@ -124,7 +124,11 @@ const runtimePlugin = (params) => ({
124
124
  /**
125
125
  * Compatible with the reference path of the old version of the plugin.
126
126
  */
127
- [`@${metaName}/runtime/plugins`]: pluginsExportsUtils.getPath()
127
+ [`@${metaName}/runtime/plugins`]: pluginsExportsUtils.getPath(),
128
+ "@meta/runtime/browser": "@modern-js/runtime/browser",
129
+ "@meta/runtime/react": "@modern-js/runtime/react",
130
+ "@meta/runtime/context": "@modern-js/runtime/context",
131
+ "@meta/runtime": "@modern-js/runtime"
128
132
  },
129
133
  globalVars: {
130
134
  "process.env.IS_REACT18": process.env.IS_REACT18
@@ -40,7 +40,7 @@ var import_constants = require("../constants");
40
40
  var import_withCallback = require("./withCallback");
41
41
  const isReact18 = () => process.env.IS_REACT18 === "true";
42
42
  function hydrateRoot(App, context, ModernRender, ModernHydrate) {
43
- var _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
43
+ var _ssrContext_request, _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
44
44
  const hydrateContext = {
45
45
  ...context,
46
46
  get routes() {
@@ -50,8 +50,8 @@ function hydrateRoot(App, context, ModernRender, ModernHydrate) {
50
50
  };
51
51
  const { ssrContext } = hydrateContext;
52
52
  const currentPathname = (0, import_url.normalizePathname)(window.location.pathname);
53
- const initialPathname = (0, import_url.normalizePathname)(ssrContext.request.pathname);
54
- if (initialPathname !== currentPathname && context.router) {
53
+ const initialPathname = (ssrContext === null || ssrContext === void 0 ? void 0 : (_ssrContext_request = ssrContext.request) === null || _ssrContext_request === void 0 ? void 0 : _ssrContext_request.pathname) && (0, import_url.normalizePathname)(ssrContext.request.pathname);
54
+ if (initialPathname && initialPathname !== currentPathname && context.router) {
55
55
  const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
56
56
  console.error(errorMsg);
57
57
  window.location.reload();
@@ -34,6 +34,7 @@ __export(code_exports, {
34
34
  module.exports = __toCommonJS(code_exports);
35
35
  var import_path = __toESM(require("path"));
36
36
  var import_utils = require("@modern-js/utils");
37
+ var import_lodash = require("@modern-js/utils/lodash");
37
38
  var import_constants = require("../constants");
38
39
  var import_constants2 = require("../../../cli/constants");
39
40
  var templates = __toESM(require("./templates"));
@@ -80,11 +81,14 @@ const generateCode = async (appContext, config, entrypoints, api) => {
80
81
  }
81
82
  }
82
83
  }
84
+ const config2 = api.useResolvedConfigContext();
85
+ const ssrByRouteIds = config2.server.ssrByRouteIds || [];
86
+ const clonedRoutes = (0, import_lodash.cloneDeep)(initialRoutes);
87
+ const markedRoutes = ssrByRouteIds.length > 0 ? markRoutes(clonedRoutes, ssrByRouteIds) : initialRoutes;
83
88
  const { routes } = await hookRunners.modifyFileSystemRoutes({
84
89
  entrypoint,
85
- routes: initialRoutes
90
+ routes: markedRoutes
86
91
  });
87
- const config2 = api.useResolvedConfigContext();
88
92
  const ssr = (0, import_utils.getEntryOptions)(entryName, isMainEntry, config2.server.ssr, config2.server.ssrByEntries, packageName);
89
93
  const useSSG = (0, import_utils.isSSGEntry)(config2, entryName, entrypoints);
90
94
  let mode;
@@ -111,23 +115,55 @@ const generateCode = async (appContext, config, entrypoints, api) => {
111
115
  })
112
116
  });
113
117
  if (entrypoint.nestedRoutesEntry && (0, import_utils.isUseSSRBundle)(config2)) {
118
+ var _config_output1;
114
119
  const routesServerFile = (0, import_utils2.getServerLoadersFile)(internalDirectory, entryName);
120
+ const filtedRoutesForServer = (0, import_utils.filterRoutesForServer)(routes);
121
+ const routesForServerLoaderMatches = (0, import_utils.filterRoutesLoader)(routes);
115
122
  const code2 = templates.routesForServer({
116
- routes
123
+ routesForServerLoaderMatches
117
124
  });
118
125
  await import_utils.fs.ensureFile(routesServerFile);
119
126
  await import_utils.fs.writeFile(routesServerFile, code2);
127
+ const serverRoutesCode = await templates.fileSystemRoutes({
128
+ metaName,
129
+ routes: filtedRoutesForServer,
130
+ ssrMode: useSSG ? "string" : mode,
131
+ nestedRoutesEntry: entrypoint.nestedRoutesEntry,
132
+ entryName: entrypoint.entryName,
133
+ internalDirectory,
134
+ splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output1 = config2.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks
135
+ });
136
+ await import_utils.fs.outputFile(import_path.default.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, "utf8");
120
137
  }
121
138
  const serverLoaderCombined = templates.ssrLoaderCombinedModule(entrypoints, entrypoint, config2, appContext);
122
139
  if (serverLoaderCombined) {
123
140
  const serverLoaderFile = (0, import_utils2.getServerCombinedModueFile)(internalDirectory, entryName);
124
141
  await import_utils.fs.outputFile(serverLoaderFile, serverLoaderCombined);
125
142
  }
126
- import_utils.fs.outputFileSync(import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
143
+ await import_utils.fs.outputFile(import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
127
144
  }
128
145
  }
129
146
  }
130
147
  };
148
+ function markRoutes(routes, routeIds) {
149
+ return routes.map((route) => {
150
+ if (route.type !== "nested") {
151
+ return route;
152
+ }
153
+ if (route.children && route.children.length > 0) {
154
+ route.children = markRoutes(route.children, routeIds);
155
+ }
156
+ if (route.children && route.children.length > 0) {
157
+ route.inValidSSRRoute = route.children.every((child) => {
158
+ var _child_inValidSSRRoute;
159
+ return (_child_inValidSSRRoute = child.inValidSSRRoute) !== null && _child_inValidSSRRoute !== void 0 ? _child_inValidSSRRoute : false;
160
+ });
161
+ } else if (route.id) {
162
+ route.inValidSSRRoute = !routeIds.includes(route.id);
163
+ }
164
+ return route;
165
+ });
166
+ }
131
167
  function generatorRegisterCode(internalDirectory, entryName, code) {
132
168
  import_utils.fs.outputFileSync(import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants2.ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}`), code, "utf8");
133
169
  }
@@ -39,7 +39,7 @@ var import_utils = require("@modern-js/utils");
39
39
  var import_constants = require("@modern-js/utils/universal/constants");
40
40
  var import_constants2 = require("../constants");
41
41
  var import_utils2 = require("./utils");
42
- const routesForServer = ({ routes }) => {
42
+ const routesForServer = ({ routesForServerLoaderMatches }) => {
43
43
  const loaders = [];
44
44
  const actions = [];
45
45
  const loadersMap = {};
@@ -82,7 +82,7 @@ const routesForServer = ({ routes }) => {
82
82
  let routesCode = `
83
83
  export const routes = [
84
84
  `;
85
- for (const route of routes) {
85
+ for (const route of routesForServerLoaderMatches) {
86
86
  if ("type" in route) {
87
87
  const keywords = [
88
88
  "loader",
@@ -135,13 +135,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
135
135
  import loadable, { lazy as loadableLazy } from "@${metaName}/runtime/loadable"
136
136
  `;
137
137
  let rootLayoutCode = ``;
138
- const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId }) => {
138
+ const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId, inValidSSRRoute }) => {
139
139
  if (!ssrMode) {
140
140
  return "";
141
141
  }
142
142
  const clientDataStr = clientData ? `&clientData=${clientData}` : "";
143
+ const retain = inValidSSRRoute !== null && inValidSSRRoute !== void 0 ? inValidSSRRoute : false;
143
144
  if (nestedRoutesEntry) {
144
- return `?loaderId=${loaderId}${clientDataStr}&action=${action ? (0, import_utils.slash)(action) : action}&inline=${inline}&routeId=${routeId}`;
145
+ return `?loaderId=${loaderId}${clientDataStr}&action=${action ? (0, import_utils.slash)(action) : action}&inline=${inline}&routeId=${routeId}&retain=${retain}`;
145
146
  }
146
147
  return "";
147
148
  };
@@ -175,6 +176,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
175
176
  loadersMap[loader] = {
176
177
  loaderId,
177
178
  routeId: route.id,
179
+ inValidSSRRoute: route.inValidSSRRoute,
178
180
  filePath: route.data || route.loader,
179
181
  clientData: Boolean(route.clientData),
180
182
  route,
@@ -299,7 +301,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
299
301
  clientData: loaderInfo.clientData,
300
302
  action: route.action,
301
303
  inline: loaderInfo.inline,
302
- routeId: loaderInfo.routeId
304
+ routeId: loaderInfo.routeId,
305
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
303
306
  })}";
304
307
  `;
305
308
  } else {
@@ -308,7 +311,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
308
311
  clientData: loaderInfo.clientData,
309
312
  action: false,
310
313
  inline: loaderInfo.inline,
311
- routeId: route.id
314
+ routeId: route.id,
315
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
312
316
  })}";
313
317
  `;
314
318
  }
@@ -318,7 +322,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
318
322
  clientData: loaderInfo.clientData,
319
323
  action: false,
320
324
  inline: loaderInfo.inline,
321
- routeId: loaderInfo.routeId
325
+ routeId: loaderInfo.routeId,
326
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
322
327
  })}";
323
328
  `;
324
329
  }
@@ -360,7 +365,17 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
360
365
  const serverLoaderRuntime = require.resolve("@modern-js/plugin-data-loader/runtime");
361
366
  const serverLoadersFile = (0, import_utils2.getServerLoadersFile)(internalDirectory, entryName);
362
367
  const combinedModule = `export * from "${(0, import_utils.slash)(serverLoaderRuntime)}"; export * from "${(0, import_utils.slash)(serverLoadersFile)}"`;
363
- return combinedModule;
368
+ if (!config.source.enableAsyncEntry) {
369
+ return combinedModule;
370
+ }
371
+ return `export default Promise.all([import("${(0, import_utils.slash)(serverLoaderRuntime)}"),import("${(0, import_utils.slash)(serverLoadersFile)}")]).then(res=>{
372
+ return res.reduce((sum,cur)=>{
373
+ return {
374
+ ...sum,
375
+ ...cur
376
+ }
377
+ },{})
378
+ })`;
364
379
  }
365
380
  return null;
366
381
  }
@@ -408,7 +423,7 @@ const runtimeGlobalContext = async ({ metaName, srcDirectory, nestedRoutesEntry,
408
423
  }
409
424
  return `${imports.join("\n")}
410
425
 
411
- import { routes } from './routes.js';
426
+ import { routes } from './routes';
412
427
 
413
428
  setGlobalContext({
414
429
  layoutApp,
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var cli_exports = {};
20
30
  __export(cli_exports, {
@@ -25,6 +35,7 @@ __export(cli_exports, {
25
35
  routerPlugin: () => routerPlugin
26
36
  });
27
37
  module.exports = __toCommonJS(cli_exports);
38
+ var import_node_path = __toESM(require("node:path"));
28
39
  var import_utils = require("@modern-js/utils");
29
40
  var import_entry = require("./entry");
30
41
  var import_handler = require("./handler");
@@ -36,6 +47,8 @@ const routerPlugin = () => ({
36
47
  "@modern-js/runtime"
37
48
  ],
38
49
  setup: (api) => {
50
+ const nestedRoutes = {};
51
+ const nestedRoutesForServer = {};
39
52
  return {
40
53
  _internalRuntimePlugins({ entrypoint, plugins }) {
41
54
  var _getEntryOptions;
@@ -60,10 +73,10 @@ const routerPlugin = () => ({
60
73
  plugins
61
74
  };
62
75
  },
63
- checkEntryPoint({ path, entry }) {
76
+ checkEntryPoint({ path: path2, entry }) {
64
77
  return {
65
- path,
66
- entry: entry || (0, import_entry.isRouteEntry)(path)
78
+ path: path2,
79
+ entry: entry || (0, import_entry.isRouteEntry)(path2)
67
80
  };
68
81
  },
69
82
  config() {
@@ -99,6 +112,22 @@ const routerPlugin = () => ({
99
112
  },
100
113
  async fileChange(e) {
101
114
  await (0, import_handler.handleFileChange)(api, e);
115
+ },
116
+ async modifyFileSystemRoutes({ entrypoint, routes }) {
117
+ nestedRoutes[entrypoint.entryName] = routes;
118
+ nestedRoutesForServer[entrypoint.entryName] = (0, import_utils.filterRoutesForServer)(routes);
119
+ return {
120
+ entrypoint,
121
+ routes
122
+ };
123
+ },
124
+ async beforeGenerateRoutes({ entrypoint, code }) {
125
+ const { distDirectory } = api.useAppContext();
126
+ await import_utils.fs.outputJSON(import_node_path.default.resolve(distDirectory, import_utils.NESTED_ROUTE_SPEC_FILE), nestedRoutesForServer);
127
+ return {
128
+ entrypoint,
129
+ code
130
+ };
102
131
  }
103
132
  };
104
133
  }
@@ -2,7 +2,7 @@ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
2
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
3
  import path from "path";
4
4
  import { MAIN_ENTRY_NAME, fs } from "@modern-js/utils";
5
- import { INDEX_FILE_NAME, ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME, ENTRY_POINT_REGISTER_FILE_NAME, ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME, SERVER_ENTRY_POINT_FILE_NAME } from "./constants";
5
+ import { INDEX_FILE_NAME, ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME, ENTRY_POINT_REGISTER_FILE_NAME, ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME, SERVER_ENTRY_POINT_FILE_NAME, ENTRY_SERVER_BOOTSTRAP_FILE_NAME } from "./constants";
6
6
  import * as template from "./template";
7
7
  import * as serverTemplate from "./template.server";
8
8
  function getSSRMode() {
@@ -35,7 +35,7 @@ var generateCode = function() {
35
35
  4,
36
36
  Promise.all(entrypoints.map(function() {
37
37
  var _ref2 = _async_to_generator(function(entrypoint) {
38
- var entryName, isAutoMount, entry, customEntry, customBootstrap, customServerEntry, _ref3, runtimePlugins, indexCode, indexFile, bootstrapFile, ssrMode, indexServerCode, indexServerFile, registerCode, registerFile, registerRuntimeCode, registerRuntimeFile, contextCode, contextFile;
38
+ var entryName, isAutoMount, entry, customEntry, customBootstrap, customServerEntry, _ref3, runtimePlugins, indexCode, indexFile, ssrMode, bootstrapFile, bootstrapServerFile, indexServerCode, indexServerFile, registerCode, registerFile, registerRuntimeCode, registerRuntimeFile, contextCode, contextFile;
39
39
  return _ts_generator(this, function(_state2) {
40
40
  switch (_state2.label) {
41
41
  case 0:
@@ -62,11 +62,15 @@ var generateCode = function() {
62
62
  });
63
63
  indexFile = path.resolve(internalDirectory, "./".concat(entryName, "/").concat(ENTRY_POINT_FILE_NAME));
64
64
  fs.outputFileSync(indexFile, indexCode, "utf8");
65
+ ssrMode = getSSRMode(entryName, config);
65
66
  if (enableAsyncEntry) {
66
67
  bootstrapFile = path.resolve(internalDirectory, "./".concat(entryName, "/").concat(ENTRY_BOOTSTRAP_FILE_NAME));
67
68
  fs.outputFileSync(bootstrapFile, "import('./".concat(INDEX_FILE_NAME, "');"), "utf8");
69
+ bootstrapServerFile = path.resolve(internalDirectory, "./".concat(entryName, "/").concat(ENTRY_SERVER_BOOTSTRAP_FILE_NAME));
70
+ if (ssrMode) {
71
+ fs.outputFileSync(bootstrapServerFile, "export const requestHandler = import('./".concat(SERVER_ENTRY_POINT_FILE_NAME, "').then((m) => m.requestHandler)"), "utf8");
72
+ }
68
73
  }
69
- ssrMode = getSSRMode(entryName, config);
70
74
  if (ssrMode) {
71
75
  indexServerCode = serverTemplate.serverIndex({
72
76
  entry,
@@ -3,6 +3,7 @@ var ENTRY_POINT_FILE_NAME = "index.jsx";
3
3
  var SERVER_ENTRY_POINT_FILE_NAME = "index.server.jsx";
4
4
  var INDEX_FILE_NAME = "index";
5
5
  var ENTRY_BOOTSTRAP_FILE_NAME = "bootstrap.jsx";
6
+ var ENTRY_SERVER_BOOTSTRAP_FILE_NAME = "bootstrap.server.jsx";
6
7
  var ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME = "runtime-register.js";
7
8
  var ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context.js";
8
9
  var ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
@@ -13,6 +14,7 @@ export {
13
14
  ENTRY_POINT_REGISTER_FILE_NAME,
14
15
  ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME,
15
16
  ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME,
17
+ ENTRY_SERVER_BOOTSTRAP_FILE_NAME,
16
18
  INDEX_FILE_NAME,
17
19
  SERVER_ENTRY_POINT_FILE_NAME
18
20
  };
@@ -94,23 +94,22 @@ var runtimePlugin = function(params) {
94
94
  var isReact18 = checkIsReact18(appDirectory);
95
95
  process.env.IS_REACT18 = isReact18.toString();
96
96
  var pluginsExportsUtils = createRuntimeExportsUtils(internalDirectory, "plugins");
97
+ var _obj;
97
98
  return {
98
99
  runtime: {},
99
100
  runtimeByEntries: {},
100
101
  source: {
101
- alias: (
102
+ alias: (_obj = {
102
103
  /**
103
- * Compatible with the reference path of the old version of the plugin.
104
+ * twin.macro inserts styled-components into the code during the compilation process
105
+ * But it will not be installed under the user project.
106
+ * So need to add alias
104
107
  */
105
- _define_property({
106
- /**
107
- * twin.macro inserts styled-components into the code during the compilation process
108
- * But it will not be installed under the user project.
109
- * So need to add alias
110
- */
111
- "styled-components": require.resolve("styled-components")
112
- }, "@".concat(metaName, "/runtime/plugins"), pluginsExportsUtils.getPath())
113
- ),
108
+ "styled-components": require.resolve("styled-components")
109
+ }, /**
110
+ * Compatible with the reference path of the old version of the plugin.
111
+ */
112
+ _define_property(_obj, "@".concat(metaName, "/runtime/plugins"), pluginsExportsUtils.getPath()), _define_property(_obj, "@meta/runtime/browser", "@modern-js/runtime/browser"), _define_property(_obj, "@meta/runtime/react", "@modern-js/runtime/react"), _define_property(_obj, "@meta/runtime/context", "@modern-js/runtime/context"), _define_property(_obj, "@meta/runtime", "@modern-js/runtime"), _obj),
114
113
  globalVars: {
115
114
  "process.env.IS_REACT18": process.env.IS_REACT18
116
115
  }
@@ -10,7 +10,7 @@ var isReact18 = function() {
10
10
  return process.env.IS_REACT18 === "true";
11
11
  };
12
12
  function hydrateRoot(App, context, ModernRender, ModernHydrate) {
13
- var _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
13
+ var _ssrContext_request, _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
14
14
  var hydrateContext = _object_spread_props(_object_spread({}, context), {
15
15
  get routes() {
16
16
  return context.routes;
@@ -19,8 +19,8 @@ function hydrateRoot(App, context, ModernRender, ModernHydrate) {
19
19
  });
20
20
  var ssrContext = hydrateContext.ssrContext;
21
21
  var currentPathname = normalizePathname(window.location.pathname);
22
- var initialPathname = normalizePathname(ssrContext.request.pathname);
23
- if (initialPathname !== currentPathname && context.router) {
22
+ var initialPathname = (ssrContext === null || ssrContext === void 0 ? void 0 : (_ssrContext_request = ssrContext.request) === null || _ssrContext_request === void 0 ? void 0 : _ssrContext_request.pathname) && normalizePathname(ssrContext.request.pathname);
23
+ if (initialPathname && initialPathname !== currentPathname && context.router) {
24
24
  var errorMsg = "The initial URL ".concat(initialPathname, " and the URL ").concat(currentPathname, " to be hydrated do not match, reload.");
25
25
  console.error(errorMsg);
26
26
  window.location.reload();
@@ -1,7 +1,8 @@
1
1
  import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
2
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
3
  import path from "path";
4
- import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger } from "@modern-js/utils";
4
+ import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger, filterRoutesForServer, filterRoutesLoader } from "@modern-js/utils";
5
+ import { cloneDeep } from "@modern-js/utils/lodash";
5
6
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants";
6
7
  import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/constants";
7
8
  import * as templates from "./templates";
@@ -16,7 +17,7 @@ var generateCode = function() {
16
17
  }
17
18
  function _generateEntryCode() {
18
19
  _generateEntryCode = _async_to_generator(function(entrypoint) {
19
- var entryName, isMainEntry, isAutoMount, pageRoutesEntry, nestedRoutesEntry, metaName, _config_output, initialRoutes, nestedRoutes, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, route, routes, _$config, ssr, useSSG, mode, hasPageRoute, code, _, _tmp, routesServerFile, code1, serverLoaderCombined, serverLoaderFile;
20
+ var entryName, isMainEntry, isAutoMount, pageRoutesEntry, nestedRoutesEntry, metaName, _config_output, initialRoutes, nestedRoutes, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, route, _$config, ssrByRouteIds, clonedRoutes, markedRoutes, routes, ssr, useSSG, mode, hasPageRoute, code, _, _tmp, _config_output1, routesServerFile, filtedRoutesForServer, routesForServerLoaderMatches, code1, serverRoutesCode, serverLoaderCombined, serverLoaderFile;
20
21
  return _ts_generator(this, function(_state) {
21
22
  switch (_state.label) {
22
23
  case 0:
@@ -25,12 +26,12 @@ var generateCode = function() {
25
26
  if (!isAutoMount)
26
27
  return [
27
28
  3,
28
- 11
29
+ 14
29
30
  ];
30
31
  if (!(pageRoutesEntry || nestedRoutesEntry))
31
32
  return [
32
33
  3,
33
- 11
34
+ 14
34
35
  ];
35
36
  initialRoutes = [];
36
37
  nestedRoutes = null;
@@ -86,16 +87,19 @@ var generateCode = function() {
86
87
  }
87
88
  _state.label = 2;
88
89
  case 2:
90
+ _$config = api.useResolvedConfigContext();
91
+ ssrByRouteIds = _$config.server.ssrByRouteIds || [];
92
+ clonedRoutes = cloneDeep(initialRoutes);
93
+ markedRoutes = ssrByRouteIds.length > 0 ? markRoutes(clonedRoutes, ssrByRouteIds) : initialRoutes;
89
94
  return [
90
95
  4,
91
96
  hookRunners.modifyFileSystemRoutes({
92
97
  entrypoint,
93
- routes: initialRoutes
98
+ routes: markedRoutes
94
99
  })
95
100
  ];
96
101
  case 3:
97
102
  routes = _state.sent().routes;
98
- _$config = api.useResolvedConfigContext();
99
103
  ssr = getEntryOptions(entryName, isMainEntry, _$config.server.ssr, _$config.server.ssrByEntries, packageName);
100
104
  useSSG = isSSGEntry(_$config, entryName, entrypoints);
101
105
  if (ssr) {
@@ -138,11 +142,13 @@ var generateCode = function() {
138
142
  if (!(entrypoint.nestedRoutesEntry && isUseSSRBundle(_$config)))
139
143
  return [
140
144
  3,
141
- 8
145
+ 10
142
146
  ];
143
147
  routesServerFile = getServerLoadersFile(internalDirectory, entryName);
148
+ filtedRoutesForServer = filterRoutesForServer(routes);
149
+ routesForServerLoaderMatches = filterRoutesLoader(routes);
144
150
  code1 = templates.routesForServer({
145
- routes
151
+ routesForServerLoaderMatches
146
152
  });
147
153
  return [
148
154
  4,
@@ -156,26 +162,51 @@ var generateCode = function() {
156
162
  ];
157
163
  case 7:
158
164
  _state.sent();
159
- _state.label = 8;
165
+ return [
166
+ 4,
167
+ templates.fileSystemRoutes({
168
+ metaName,
169
+ routes: filtedRoutesForServer,
170
+ ssrMode: useSSG ? "string" : mode,
171
+ nestedRoutesEntry: entrypoint.nestedRoutesEntry,
172
+ entryName: entrypoint.entryName,
173
+ internalDirectory,
174
+ splitRouteChunks: _$config === null || _$config === void 0 ? void 0 : (_config_output1 = _$config.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks
175
+ })
176
+ ];
160
177
  case 8:
178
+ serverRoutesCode = _state.sent();
179
+ return [
180
+ 4,
181
+ fs.outputFile(path.resolve(internalDirectory, "./".concat(entryName, "/routes.server.js")), serverRoutesCode, "utf8")
182
+ ];
183
+ case 9:
184
+ _state.sent();
185
+ _state.label = 10;
186
+ case 10:
161
187
  serverLoaderCombined = templates.ssrLoaderCombinedModule(entrypoints, entrypoint, _$config, appContext);
162
188
  if (!serverLoaderCombined)
163
189
  return [
164
190
  3,
165
- 10
191
+ 12
166
192
  ];
167
193
  serverLoaderFile = getServerCombinedModueFile(internalDirectory, entryName);
168
194
  return [
169
195
  4,
170
196
  fs.outputFile(serverLoaderFile, serverLoaderCombined)
171
197
  ];
172
- case 9:
173
- _state.sent();
174
- _state.label = 10;
175
- case 10:
176
- fs.outputFileSync(path.resolve(internalDirectory, "./".concat(entryName, "/").concat(FILE_SYSTEM_ROUTES_FILE_NAME)), code, "utf8");
177
- _state.label = 11;
178
198
  case 11:
199
+ _state.sent();
200
+ _state.label = 12;
201
+ case 12:
202
+ return [
203
+ 4,
204
+ fs.outputFile(path.resolve(internalDirectory, "./".concat(entryName, "/").concat(FILE_SYSTEM_ROUTES_FILE_NAME)), code, "utf8")
205
+ ];
206
+ case 13:
207
+ _state.sent();
208
+ _state.label = 14;
209
+ case 14:
179
210
  return [
180
211
  2
181
212
  ];
@@ -208,6 +239,25 @@ var generateCode = function() {
208
239
  return _ref.apply(this, arguments);
209
240
  };
210
241
  }();
242
+ function markRoutes(routes, routeIds) {
243
+ return routes.map(function(route) {
244
+ if (route.type !== "nested") {
245
+ return route;
246
+ }
247
+ if (route.children && route.children.length > 0) {
248
+ route.children = markRoutes(route.children, routeIds);
249
+ }
250
+ if (route.children && route.children.length > 0) {
251
+ route.inValidSSRRoute = route.children.every(function(child) {
252
+ var _child_inValidSSRRoute;
253
+ return (_child_inValidSSRRoute = child.inValidSSRRoute) !== null && _child_inValidSSRRoute !== void 0 ? _child_inValidSSRRoute : false;
254
+ });
255
+ } else if (route.id) {
256
+ route.inValidSSRRoute = !routeIds.includes(route.id);
257
+ }
258
+ return route;
259
+ });
260
+ }
211
261
  function generatorRegisterCode(internalDirectory, entryName, code) {
212
262
  fs.outputFileSync(path.resolve(internalDirectory, "./".concat(entryName, "/").concat(ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME)), code, "utf8");
213
263
  }
@@ -9,7 +9,7 @@ import { ROUTE_MODULES } from "@modern-js/utils/universal/constants";
9
9
  import { APP_CONFIG_NAME, APP_INIT_EXPORTED, TEMP_LOADERS_DIR } from "../constants";
10
10
  import { getPathWithoutExt, getServerLoadersFile, parseModule, replaceWithAlias } from "./utils";
11
11
  var routesForServer = function(param) {
12
- var routes = param.routes;
12
+ var routesForServerLoaderMatches = param.routesForServerLoaderMatches;
13
13
  var loaders = [];
14
14
  var actions = [];
15
15
  var loadersMap = {};
@@ -51,7 +51,7 @@ var routesForServer = function(param) {
51
51
  var routesCode = "\n export const routes = [\n ";
52
52
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
53
53
  try {
54
- for (var _iterator = routes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
54
+ for (var _iterator = routesForServerLoaderMatches[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
55
55
  var route = _step.value;
56
56
  if ("type" in route) {
57
57
  var keywords = [
@@ -136,13 +136,14 @@ var fileSystemRoutes = function() {
136
136
  importLazyCode = '\n import { lazy } from "react";\n import loadable, { lazy as loadableLazy } from "@'.concat(metaName, '/runtime/loadable"\n ');
137
137
  rootLayoutCode = "";
138
138
  getDataLoaderPath = function(param2) {
139
- var loaderId = param2.loaderId, clientData = param2.clientData, action = param2.action, inline = param2.inline, routeId = param2.routeId;
139
+ var loaderId = param2.loaderId, clientData = param2.clientData, action = param2.action, inline = param2.inline, routeId = param2.routeId, inValidSSRRoute = param2.inValidSSRRoute;
140
140
  if (!ssrMode) {
141
141
  return "";
142
142
  }
143
143
  var clientDataStr = clientData ? "&clientData=".concat(clientData) : "";
144
+ var retain = inValidSSRRoute !== null && inValidSSRRoute !== void 0 ? inValidSSRRoute : false;
144
145
  if (nestedRoutesEntry) {
145
- return "?loaderId=".concat(loaderId).concat(clientDataStr, "&action=").concat(action ? slash(action) : action, "&inline=").concat(inline, "&routeId=").concat(routeId);
146
+ return "?loaderId=".concat(loaderId).concat(clientDataStr, "&action=").concat(action ? slash(action) : action, "&inline=").concat(inline, "&routeId=").concat(routeId, "&retain=").concat(retain);
146
147
  }
147
148
  return "";
148
149
  };
@@ -176,6 +177,7 @@ var fileSystemRoutes = function() {
176
177
  loadersMap[loader] = {
177
178
  loaderId,
178
179
  routeId: route2.id,
180
+ inValidSSRRoute: route2.inValidSSRRoute,
179
181
  filePath: route2.data || route2.loader,
180
182
  clientData: Boolean(route2.clientData),
181
183
  route: route2,
@@ -316,7 +318,8 @@ var fileSystemRoutes = function() {
316
318
  clientData: loaderInfo.clientData,
317
319
  action: route1.action,
318
320
  inline: loaderInfo.inline,
319
- routeId: loaderInfo.routeId
321
+ routeId: loaderInfo.routeId,
322
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
320
323
  }), '";\n');
321
324
  } else {
322
325
  importLoadersCode += "import { loader as ".concat(key, ' } from "').concat(slash(loaderInfo.filePath)).concat(getDataLoaderPath({
@@ -324,7 +327,8 @@ var fileSystemRoutes = function() {
324
327
  clientData: loaderInfo.clientData,
325
328
  action: false,
326
329
  inline: loaderInfo.inline,
327
- routeId: route1.id
330
+ routeId: route1.id,
331
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
328
332
  }), '";\n');
329
333
  }
330
334
  } else {
@@ -333,7 +337,8 @@ var fileSystemRoutes = function() {
333
337
  clientData: loaderInfo.clientData,
334
338
  action: false,
335
339
  inline: loaderInfo.inline,
336
- routeId: loaderInfo.routeId
340
+ routeId: loaderInfo.routeId,
341
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
337
342
  }), '";\n');
338
343
  }
339
344
  }
@@ -406,7 +411,10 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
406
411
  var serverLoaderRuntime = require.resolve("@modern-js/plugin-data-loader/runtime");
407
412
  var serverLoadersFile = getServerLoadersFile(internalDirectory, entryName);
408
413
  var combinedModule = 'export * from "'.concat(slash(serverLoaderRuntime), '"; export * from "').concat(slash(serverLoadersFile), '"');
409
- return combinedModule;
414
+ if (!config.source.enableAsyncEntry) {
415
+ return combinedModule;
416
+ }
417
+ return 'export default Promise.all([import("'.concat(slash(serverLoaderRuntime), '"),import("').concat(slash(serverLoadersFile), '")]).then(res=>{\n return res.reduce((sum,cur)=>{\n return {\n ...sum,\n ...cur\n }\n },{})\n })');
410
418
  }
411
419
  return null;
412
420
  }
@@ -493,7 +501,7 @@ var runtimeGlobalContext = function() {
493
501
  }
494
502
  return [
495
503
  2,
496
- "".concat(imports.join("\n"), "\n\nimport { routes } from './routes.js';\n\nsetGlobalContext({\n layoutApp,\n routes,\n appInit,\n appConfig,\n});")
504
+ "".concat(imports.join("\n"), "\n\nimport { routes } from './routes';\n\nsetGlobalContext({\n layoutApp,\n routes,\n appInit,\n appConfig,\n});")
497
505
  ];
498
506
  }
499
507
  });
@@ -2,7 +2,8 @@ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
2
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
3
3
  import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
4
4
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
5
- import { createRuntimeExportsUtils, getEntryOptions, isRouterV5 as isV5 } from "@modern-js/utils";
5
+ import path from "node:path";
6
+ import { createRuntimeExportsUtils, filterRoutesForServer, fs, getEntryOptions, isRouterV5 as isV5, NESTED_ROUTE_SPEC_FILE } from "@modern-js/utils";
6
7
  import { isRouteEntry } from "./entry";
7
8
  import { handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints } from "./handler";
8
9
  import { isRouteEntry as isRouteEntry2 } from "./entry";
@@ -14,6 +15,8 @@ var routerPlugin = function() {
14
15
  "@modern-js/runtime"
15
16
  ],
16
17
  setup: function(api) {
18
+ var nestedRoutes = {};
19
+ var nestedRoutesForServer = {};
17
20
  return {
18
21
  _internalRuntimePlugins: function _internalRuntimePlugins(param) {
19
22
  var entrypoint = param.entrypoint, plugins = param.plugins;
@@ -45,10 +48,10 @@ var routerPlugin = function() {
45
48
  };
46
49
  },
47
50
  checkEntryPoint: function checkEntryPoint(param) {
48
- var path = param.path, entry = param.entry;
51
+ var path2 = param.path, entry = param.entry;
49
52
  return {
50
- path,
51
- entry: entry || isRouteEntry(path)
53
+ path: path2,
54
+ entry: entry || isRouteEntry(path2)
52
55
  };
53
56
  },
54
57
  config: function config() {
@@ -132,6 +135,47 @@ var routerPlugin = function() {
132
135
  }
133
136
  });
134
137
  })();
138
+ },
139
+ modifyFileSystemRoutes: function modifyFileSystemRoutes(param) {
140
+ var entrypoint = param.entrypoint, routes = param.routes;
141
+ return _async_to_generator(function() {
142
+ return _ts_generator(this, function(_state) {
143
+ nestedRoutes[entrypoint.entryName] = routes;
144
+ nestedRoutesForServer[entrypoint.entryName] = filterRoutesForServer(routes);
145
+ return [
146
+ 2,
147
+ {
148
+ entrypoint,
149
+ routes
150
+ }
151
+ ];
152
+ });
153
+ })();
154
+ },
155
+ beforeGenerateRoutes: function beforeGenerateRoutes(param) {
156
+ var entrypoint = param.entrypoint, code = param.code;
157
+ return _async_to_generator(function() {
158
+ var distDirectory;
159
+ return _ts_generator(this, function(_state) {
160
+ switch (_state.label) {
161
+ case 0:
162
+ distDirectory = api.useAppContext().distDirectory;
163
+ return [
164
+ 4,
165
+ fs.outputJSON(path.resolve(distDirectory, NESTED_ROUTE_SPEC_FILE), nestedRoutesForServer)
166
+ ];
167
+ case 1:
168
+ _state.sent();
169
+ return [
170
+ 2,
171
+ {
172
+ entrypoint,
173
+ code
174
+ }
175
+ ];
176
+ }
177
+ });
178
+ })();
135
179
  }
136
180
  };
137
181
  }
@@ -1,6 +1,6 @@
1
1
  import path from "path";
2
2
  import { MAIN_ENTRY_NAME, fs } from "@modern-js/utils";
3
- import { INDEX_FILE_NAME, ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME, ENTRY_POINT_REGISTER_FILE_NAME, ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME, SERVER_ENTRY_POINT_FILE_NAME } from "./constants";
3
+ import { INDEX_FILE_NAME, ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME, ENTRY_POINT_REGISTER_FILE_NAME, ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME, SERVER_ENTRY_POINT_FILE_NAME, ENTRY_SERVER_BOOTSTRAP_FILE_NAME } from "./constants";
4
4
  import * as template from "./template";
5
5
  import * as serverTemplate from "./template.server";
6
6
  function getSSRMode(entry = MAIN_ENTRY_NAME, config) {
@@ -42,11 +42,15 @@ const generateCode = async (entrypoints, appContext, config, onCollectRuntimePlu
42
42
  });
43
43
  const indexFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_FILE_NAME}`);
44
44
  fs.outputFileSync(indexFile, indexCode, "utf8");
45
+ const ssrMode = getSSRMode(entryName, config);
45
46
  if (enableAsyncEntry) {
46
47
  const bootstrapFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_BOOTSTRAP_FILE_NAME}`);
47
48
  fs.outputFileSync(bootstrapFile, `import('./${INDEX_FILE_NAME}');`, "utf8");
49
+ const bootstrapServerFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_SERVER_BOOTSTRAP_FILE_NAME}`);
50
+ if (ssrMode) {
51
+ fs.outputFileSync(bootstrapServerFile, `export const requestHandler = import('./${SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, "utf8");
52
+ }
48
53
  }
49
- const ssrMode = getSSRMode(entryName, config);
50
54
  if (ssrMode) {
51
55
  const indexServerCode = serverTemplate.serverIndex({
52
56
  entry,
@@ -3,6 +3,7 @@ const ENTRY_POINT_FILE_NAME = "index.jsx";
3
3
  const SERVER_ENTRY_POINT_FILE_NAME = "index.server.jsx";
4
4
  const INDEX_FILE_NAME = "index";
5
5
  const ENTRY_BOOTSTRAP_FILE_NAME = "bootstrap.jsx";
6
+ const ENTRY_SERVER_BOOTSTRAP_FILE_NAME = "bootstrap.server.jsx";
6
7
  const ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME = "runtime-register.js";
7
8
  const ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context.js";
8
9
  const ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
@@ -13,6 +14,7 @@ export {
13
14
  ENTRY_POINT_REGISTER_FILE_NAME,
14
15
  ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME,
15
16
  ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME,
17
+ ENTRY_SERVER_BOOTSTRAP_FILE_NAME,
16
18
  INDEX_FILE_NAME,
17
19
  SERVER_ENTRY_POINT_FILE_NAME
18
20
  };
@@ -85,7 +85,11 @@ const runtimePlugin = (params) => ({
85
85
  /**
86
86
  * Compatible with the reference path of the old version of the plugin.
87
87
  */
88
- [`@${metaName}/runtime/plugins`]: pluginsExportsUtils.getPath()
88
+ [`@${metaName}/runtime/plugins`]: pluginsExportsUtils.getPath(),
89
+ "@meta/runtime/browser": "@modern-js/runtime/browser",
90
+ "@meta/runtime/react": "@modern-js/runtime/react",
91
+ "@meta/runtime/context": "@modern-js/runtime/context",
92
+ "@meta/runtime": "@modern-js/runtime"
89
93
  },
90
94
  globalVars: {
91
95
  "process.env.IS_REACT18": process.env.IS_REACT18
@@ -6,7 +6,7 @@ import { RenderLevel } from "../constants";
6
6
  import { WithCallback } from "./withCallback";
7
7
  const isReact18 = () => process.env.IS_REACT18 === "true";
8
8
  function hydrateRoot(App, context, ModernRender, ModernHydrate) {
9
- var _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
9
+ var _ssrContext_request, _window__SSR_DATA, _window, _window__SSR_DATA1, _window1;
10
10
  const hydrateContext = {
11
11
  ...context,
12
12
  get routes() {
@@ -16,8 +16,8 @@ function hydrateRoot(App, context, ModernRender, ModernHydrate) {
16
16
  };
17
17
  const { ssrContext } = hydrateContext;
18
18
  const currentPathname = normalizePathname(window.location.pathname);
19
- const initialPathname = normalizePathname(ssrContext.request.pathname);
20
- if (initialPathname !== currentPathname && context.router) {
19
+ const initialPathname = (ssrContext === null || ssrContext === void 0 ? void 0 : (_ssrContext_request = ssrContext.request) === null || _ssrContext_request === void 0 ? void 0 : _ssrContext_request.pathname) && normalizePathname(ssrContext.request.pathname);
20
+ if (initialPathname && initialPathname !== currentPathname && context.router) {
21
21
  const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
22
22
  console.error(errorMsg);
23
23
  window.location.reload();
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
- import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger } from "@modern-js/utils";
2
+ import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger, filterRoutesForServer, filterRoutesLoader } from "@modern-js/utils";
3
+ import { cloneDeep } from "@modern-js/utils/lodash";
3
4
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants";
4
5
  import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/constants";
5
6
  import * as templates from "./templates";
@@ -46,11 +47,14 @@ const generateCode = async (appContext, config, entrypoints, api) => {
46
47
  }
47
48
  }
48
49
  }
50
+ const config2 = api.useResolvedConfigContext();
51
+ const ssrByRouteIds = config2.server.ssrByRouteIds || [];
52
+ const clonedRoutes = cloneDeep(initialRoutes);
53
+ const markedRoutes = ssrByRouteIds.length > 0 ? markRoutes(clonedRoutes, ssrByRouteIds) : initialRoutes;
49
54
  const { routes } = await hookRunners.modifyFileSystemRoutes({
50
55
  entrypoint,
51
- routes: initialRoutes
56
+ routes: markedRoutes
52
57
  });
53
- const config2 = api.useResolvedConfigContext();
54
58
  const ssr = getEntryOptions(entryName, isMainEntry, config2.server.ssr, config2.server.ssrByEntries, packageName);
55
59
  const useSSG = isSSGEntry(config2, entryName, entrypoints);
56
60
  let mode;
@@ -77,23 +81,55 @@ const generateCode = async (appContext, config, entrypoints, api) => {
77
81
  })
78
82
  });
79
83
  if (entrypoint.nestedRoutesEntry && isUseSSRBundle(config2)) {
84
+ var _config_output1;
80
85
  const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
86
+ const filtedRoutesForServer = filterRoutesForServer(routes);
87
+ const routesForServerLoaderMatches = filterRoutesLoader(routes);
81
88
  const code2 = templates.routesForServer({
82
- routes
89
+ routesForServerLoaderMatches
83
90
  });
84
91
  await fs.ensureFile(routesServerFile);
85
92
  await fs.writeFile(routesServerFile, code2);
93
+ const serverRoutesCode = await templates.fileSystemRoutes({
94
+ metaName,
95
+ routes: filtedRoutesForServer,
96
+ ssrMode: useSSG ? "string" : mode,
97
+ nestedRoutesEntry: entrypoint.nestedRoutesEntry,
98
+ entryName: entrypoint.entryName,
99
+ internalDirectory,
100
+ splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output1 = config2.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks
101
+ });
102
+ await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, "utf8");
86
103
  }
87
104
  const serverLoaderCombined = templates.ssrLoaderCombinedModule(entrypoints, entrypoint, config2, appContext);
88
105
  if (serverLoaderCombined) {
89
106
  const serverLoaderFile = getServerCombinedModueFile(internalDirectory, entryName);
90
107
  await fs.outputFile(serverLoaderFile, serverLoaderCombined);
91
108
  }
92
- fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
109
+ await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
93
110
  }
94
111
  }
95
112
  }
96
113
  };
114
+ function markRoutes(routes, routeIds) {
115
+ return routes.map((route) => {
116
+ if (route.type !== "nested") {
117
+ return route;
118
+ }
119
+ if (route.children && route.children.length > 0) {
120
+ route.children = markRoutes(route.children, routeIds);
121
+ }
122
+ if (route.children && route.children.length > 0) {
123
+ route.inValidSSRRoute = route.children.every((child) => {
124
+ var _child_inValidSSRRoute;
125
+ return (_child_inValidSSRRoute = child.inValidSSRRoute) !== null && _child_inValidSSRRoute !== void 0 ? _child_inValidSSRRoute : false;
126
+ });
127
+ } else if (route.id) {
128
+ route.inValidSSRRoute = !routeIds.includes(route.id);
129
+ }
130
+ return route;
131
+ });
132
+ }
97
133
  function generatorRegisterCode(internalDirectory, entryName, code) {
98
134
  fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}`), code, "utf8");
99
135
  }
@@ -3,7 +3,7 @@ import { findExists, formatImportPath, fs, getEntryOptions, isSSGEntry, slash }
3
3
  import { ROUTE_MODULES } from "@modern-js/utils/universal/constants";
4
4
  import { APP_CONFIG_NAME, APP_INIT_EXPORTED, TEMP_LOADERS_DIR } from "../constants";
5
5
  import { getPathWithoutExt, getServerLoadersFile, parseModule, replaceWithAlias } from "./utils";
6
- const routesForServer = ({ routes }) => {
6
+ const routesForServer = ({ routesForServerLoaderMatches }) => {
7
7
  const loaders = [];
8
8
  const actions = [];
9
9
  const loadersMap = {};
@@ -46,7 +46,7 @@ const routesForServer = ({ routes }) => {
46
46
  let routesCode = `
47
47
  export const routes = [
48
48
  `;
49
- for (const route of routes) {
49
+ for (const route of routesForServerLoaderMatches) {
50
50
  if ("type" in route) {
51
51
  const keywords = [
52
52
  "loader",
@@ -99,13 +99,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
99
99
  import loadable, { lazy as loadableLazy } from "@${metaName}/runtime/loadable"
100
100
  `;
101
101
  let rootLayoutCode = ``;
102
- const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId }) => {
102
+ const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId, inValidSSRRoute }) => {
103
103
  if (!ssrMode) {
104
104
  return "";
105
105
  }
106
106
  const clientDataStr = clientData ? `&clientData=${clientData}` : "";
107
+ const retain = inValidSSRRoute !== null && inValidSSRRoute !== void 0 ? inValidSSRRoute : false;
107
108
  if (nestedRoutesEntry) {
108
- return `?loaderId=${loaderId}${clientDataStr}&action=${action ? slash(action) : action}&inline=${inline}&routeId=${routeId}`;
109
+ return `?loaderId=${loaderId}${clientDataStr}&action=${action ? slash(action) : action}&inline=${inline}&routeId=${routeId}&retain=${retain}`;
109
110
  }
110
111
  return "";
111
112
  };
@@ -139,6 +140,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
139
140
  loadersMap[loader] = {
140
141
  loaderId,
141
142
  routeId: route.id,
143
+ inValidSSRRoute: route.inValidSSRRoute,
142
144
  filePath: route.data || route.loader,
143
145
  clientData: Boolean(route.clientData),
144
146
  route,
@@ -263,7 +265,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
263
265
  clientData: loaderInfo.clientData,
264
266
  action: route.action,
265
267
  inline: loaderInfo.inline,
266
- routeId: loaderInfo.routeId
268
+ routeId: loaderInfo.routeId,
269
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
267
270
  })}";
268
271
  `;
269
272
  } else {
@@ -272,7 +275,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
272
275
  clientData: loaderInfo.clientData,
273
276
  action: false,
274
277
  inline: loaderInfo.inline,
275
- routeId: route.id
278
+ routeId: route.id,
279
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
276
280
  })}";
277
281
  `;
278
282
  }
@@ -282,7 +286,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
282
286
  clientData: loaderInfo.clientData,
283
287
  action: false,
284
288
  inline: loaderInfo.inline,
285
- routeId: loaderInfo.routeId
289
+ routeId: loaderInfo.routeId,
290
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
286
291
  })}";
287
292
  `;
288
293
  }
@@ -324,7 +329,17 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
324
329
  const serverLoaderRuntime = require.resolve("@modern-js/plugin-data-loader/runtime");
325
330
  const serverLoadersFile = getServerLoadersFile(internalDirectory, entryName);
326
331
  const combinedModule = `export * from "${slash(serverLoaderRuntime)}"; export * from "${slash(serverLoadersFile)}"`;
327
- return combinedModule;
332
+ if (!config.source.enableAsyncEntry) {
333
+ return combinedModule;
334
+ }
335
+ return `export default Promise.all([import("${slash(serverLoaderRuntime)}"),import("${slash(serverLoadersFile)}")]).then(res=>{
336
+ return res.reduce((sum,cur)=>{
337
+ return {
338
+ ...sum,
339
+ ...cur
340
+ }
341
+ },{})
342
+ })`;
328
343
  }
329
344
  return null;
330
345
  }
@@ -372,7 +387,7 @@ const runtimeGlobalContext = async ({ metaName, srcDirectory, nestedRoutesEntry,
372
387
  }
373
388
  return `${imports.join("\n")}
374
389
 
375
- import { routes } from './routes.js';
390
+ import { routes } from './routes';
376
391
 
377
392
  setGlobalContext({
378
393
  layoutApp,
@@ -1,4 +1,5 @@
1
- import { createRuntimeExportsUtils, getEntryOptions, isRouterV5 as isV5 } from "@modern-js/utils";
1
+ import path from "node:path";
2
+ import { createRuntimeExportsUtils, filterRoutesForServer, fs, getEntryOptions, isRouterV5 as isV5, NESTED_ROUTE_SPEC_FILE } from "@modern-js/utils";
2
3
  import { isRouteEntry } from "./entry";
3
4
  import { handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints } from "./handler";
4
5
  import { isRouteEntry as isRouteEntry2 } from "./entry";
@@ -9,6 +10,8 @@ const routerPlugin = () => ({
9
10
  "@modern-js/runtime"
10
11
  ],
11
12
  setup: (api) => {
13
+ const nestedRoutes = {};
14
+ const nestedRoutesForServer = {};
12
15
  return {
13
16
  _internalRuntimePlugins({ entrypoint, plugins }) {
14
17
  var _getEntryOptions;
@@ -33,10 +36,10 @@ const routerPlugin = () => ({
33
36
  plugins
34
37
  };
35
38
  },
36
- checkEntryPoint({ path, entry }) {
39
+ checkEntryPoint({ path: path2, entry }) {
37
40
  return {
38
- path,
39
- entry: entry || isRouteEntry(path)
41
+ path: path2,
42
+ entry: entry || isRouteEntry(path2)
40
43
  };
41
44
  },
42
45
  config() {
@@ -72,6 +75,22 @@ const routerPlugin = () => ({
72
75
  },
73
76
  async fileChange(e) {
74
77
  await handleFileChange(api, e);
78
+ },
79
+ async modifyFileSystemRoutes({ entrypoint, routes }) {
80
+ nestedRoutes[entrypoint.entryName] = routes;
81
+ nestedRoutesForServer[entrypoint.entryName] = filterRoutesForServer(routes);
82
+ return {
83
+ entrypoint,
84
+ routes
85
+ };
86
+ },
87
+ async beforeGenerateRoutes({ entrypoint, code }) {
88
+ const { distDirectory } = api.useAppContext();
89
+ await fs.outputJSON(path.resolve(distDirectory, NESTED_ROUTE_SPEC_FILE), nestedRoutesForServer);
90
+ return {
91
+ entrypoint,
92
+ code
93
+ };
75
94
  }
76
95
  };
77
96
  }
@@ -3,6 +3,7 @@ export declare const ENTRY_POINT_FILE_NAME = "index.jsx";
3
3
  export declare const SERVER_ENTRY_POINT_FILE_NAME = "index.server.jsx";
4
4
  export declare const INDEX_FILE_NAME = "index";
5
5
  export declare const ENTRY_BOOTSTRAP_FILE_NAME = "bootstrap.jsx";
6
+ export declare const ENTRY_SERVER_BOOTSTRAP_FILE_NAME = "bootstrap.server.jsx";
6
7
  export declare const ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME = "runtime-register.js";
7
8
  export declare const ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context.js";
8
9
  export declare const ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
@@ -1,5 +1,5 @@
1
1
  import { AfterMatchContext, AfterRenderContext, MiddlewareContext, NextFunction } from '@modern-js/types';
2
- export type { Container, CacheControl, CacheOptionProvider, CacheOption, UnstableMiddlewareContext, UnstableMiddleware, UnstableNext, } from '@modern-js/types';
2
+ export type { Container, CacheControl, CacheOptionProvider, CacheOption, UnstableMiddlewareContext, UnstableMiddleware, UnstableNext, MonitorEvent, Monitors, CoreMonitor, LogEvent, LogLevel, TimingEvent, } from '@modern-js/types';
3
3
  export declare const hook: (attacher: ({ addMiddleware, afterMatch, afterRender, }: {
4
4
  addMiddleware: (mid: Middleware) => void;
5
5
  afterRender: (hook: AfterRenderHook) => void;
@@ -1,7 +1,7 @@
1
1
  import type { Entrypoint, NestedRouteForCli, PageRoute, RouteLegacy, SSRMode } from '@modern-js/types';
2
2
  import type { AppNormalizedConfig, IAppContext } from '@modern-js/app-tools';
3
- export declare const routesForServer: ({ routes, }: {
4
- routes: (NestedRouteForCli | PageRoute)[];
3
+ export declare const routesForServer: ({ routesForServerLoaderMatches, }: {
4
+ routesForServerLoaderMatches: (NestedRouteForCli | PageRoute)[];
5
5
  }) => string;
6
6
  export declare const fileSystemRoutes: ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks, }: {
7
7
  metaName: string;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.56.1",
18
+ "version": "2.56.3-alpha.0",
19
19
  "engines": {
20
20
  "node": ">=14.17.6"
21
21
  },
@@ -199,11 +199,11 @@
199
199
  "react-side-effect": "^2.1.1",
200
200
  "styled-components": "^5.3.1",
201
201
  "@swc/helpers": "0.5.3",
202
- "@modern-js/types": "2.56.1",
203
- "@modern-js/plugin": "2.56.1",
204
- "@modern-js/utils": "2.56.1",
205
- "@modern-js/plugin-data-loader": "2.56.1",
206
- "@modern-js/runtime-utils": "2.56.1"
202
+ "@modern-js/plugin": "2.56.2",
203
+ "@modern-js/utils": "2.56.2",
204
+ "@modern-js/types": "2.56.2",
205
+ "@modern-js/runtime-utils": "2.56.2",
206
+ "@modern-js/plugin-data-loader": "2.56.2"
207
207
  },
208
208
  "peerDependencies": {
209
209
  "react": ">=17",
@@ -226,16 +226,15 @@
226
226
  "ts-jest": "^29.1.0",
227
227
  "typescript": "^5",
228
228
  "webpack": "^5.93.0",
229
- "@modern-js/app-tools": "2.56.1",
230
- "@modern-js/core": "2.56.1",
231
- "@scripts/build": "2.56.1",
232
- "@scripts/jest-config": "2.56.1"
229
+ "@modern-js/app-tools": "2.56.2",
230
+ "@modern-js/core": "2.56.2",
231
+ "@scripts/build": "2.56.2",
232
+ "@scripts/jest-config": "2.56.2"
233
233
  },
234
234
  "sideEffects": false,
235
235
  "publishConfig": {
236
236
  "registry": "https://registry.npmjs.org/",
237
- "access": "public",
238
- "provenance": true
237
+ "access": "public"
239
238
  },
240
239
  "scripts": {
241
240
  "dev": "modern-lib build --watch",