@bleedingdev/modern-js-app-tools 3.9.0-ultramodern.9 → 3.9.3-ultramodern.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.
Files changed (145) hide show
  1. package/bin/modern-bundle-docs.js +2 -2
  2. package/bin/modern.js +2 -2
  3. package/dist/cjs/builder/generator/adapterCopy.js +26 -0
  4. package/dist/cjs/builder/generator/createCopyPattern.js +2 -1
  5. package/dist/cjs/builder/index.js +4 -0
  6. package/dist/cjs/builder/shared/builderPlugins/adapterHtml.js +2 -1
  7. package/dist/cjs/builder/shared/builderPlugins/adapterSSR.js +11 -6
  8. package/dist/cjs/builder/shared/lazyCompilation.js +26 -0
  9. package/dist/cjs/commands/build.js +1 -2
  10. package/dist/cjs/commands/deploy.js +1 -3
  11. package/dist/cjs/commands/index.js +10 -2
  12. package/dist/cjs/compat/hooks.js +1 -1
  13. package/dist/cjs/esm/ts-paths-loader.js +5 -4
  14. package/dist/cjs/esm/ts-paths-loader.mjs +5 -4
  15. package/dist/cjs/index.js +73 -99
  16. package/dist/cjs/plugins/analyze/getFileSystemEntry.js +1 -1
  17. package/dist/cjs/plugins/analyze/getServerRoutes.js +1 -1
  18. package/dist/cjs/plugins/analyze/index.js +2 -2
  19. package/dist/cjs/plugins/analyze/utils.js +6 -6
  20. package/dist/cjs/plugins/deploy/index.js +7 -28
  21. package/dist/cjs/plugins/deploy/platforms/netlify.js +2 -1
  22. package/dist/cjs/plugins/deploy/platforms/node.js +12 -3
  23. package/dist/cjs/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  24. package/dist/cjs/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  25. package/dist/cjs/plugins/deploy/platforms/vercel.js +2 -1
  26. package/dist/cjs/plugins/deploy/utils/index.js +15 -12
  27. package/dist/cjs/plugins/initialize/index.js +6 -5
  28. package/dist/cjs/plugins/serverBuild.js +0 -2
  29. package/dist/cjs/run/index.js +5 -5
  30. package/dist/cjs/types/config/base.js +62 -0
  31. package/dist/cjs/types/plugin-base.js +18 -0
  32. package/dist/cjs/types/plugin.js +46 -2
  33. package/dist/cjs/utils/initAppContext.js +1 -1
  34. package/dist/cjs/utils/loadPlugins.js +13 -7
  35. package/dist/cjs/utils/register.js +1 -1
  36. package/dist/esm/builder/generator/adapterCopy.mjs +23 -1
  37. package/dist/esm/builder/generator/createCopyPattern.mjs +2 -1
  38. package/dist/esm/builder/index.mjs +1 -0
  39. package/dist/esm/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
  40. package/dist/esm/builder/shared/builderPlugins/adapterSSR.mjs +9 -7
  41. package/dist/esm/builder/shared/lazyCompilation.mjs +14 -1
  42. package/dist/esm/commands/build.mjs +1 -2
  43. package/dist/esm/commands/deploy.mjs +1 -3
  44. package/dist/esm/commands/index.mjs +10 -2
  45. package/dist/esm/compat/hooks.mjs +1 -1
  46. package/dist/esm/esm/ts-paths-loader.mjs +5 -4
  47. package/dist/esm/index.mjs +9 -18
  48. package/dist/esm/plugins/analyze/getFileSystemEntry.mjs +1 -1
  49. package/dist/esm/plugins/analyze/getServerRoutes.mjs +1 -1
  50. package/dist/esm/plugins/analyze/index.mjs +2 -2
  51. package/dist/esm/plugins/analyze/utils.mjs +7 -7
  52. package/dist/esm/plugins/deploy/index.mjs +5 -21
  53. package/dist/esm/plugins/deploy/platforms/netlify.mjs +2 -1
  54. package/dist/esm/plugins/deploy/platforms/node.mjs +12 -3
  55. package/dist/esm/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  56. package/dist/esm/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  57. package/dist/esm/plugins/deploy/platforms/vercel.mjs +2 -1
  58. package/dist/esm/plugins/deploy/utils/index.mjs +17 -14
  59. package/dist/esm/plugins/initialize/index.mjs +6 -5
  60. package/dist/esm/plugins/serverBuild.mjs +0 -2
  61. package/dist/esm/run/index.mjs +5 -5
  62. package/dist/esm/types/config/base.mjs +1 -0
  63. package/dist/esm/types/plugin-base.mjs +0 -0
  64. package/dist/esm/types/plugin.mjs +1 -0
  65. package/dist/esm/utils/initAppContext.mjs +2 -2
  66. package/dist/esm/utils/loadPlugins.mjs +4 -8
  67. package/dist/esm/utils/register.mjs +1 -1
  68. package/dist/esm-node/builder/generator/adapterCopy.mjs +23 -1
  69. package/dist/esm-node/builder/generator/createCopyPattern.mjs +2 -1
  70. package/dist/esm-node/builder/index.mjs +1 -0
  71. package/dist/esm-node/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
  72. package/dist/esm-node/builder/shared/builderPlugins/adapterSSR.mjs +9 -7
  73. package/dist/esm-node/builder/shared/lazyCompilation.mjs +14 -1
  74. package/dist/esm-node/commands/build.mjs +1 -2
  75. package/dist/esm-node/commands/deploy.mjs +1 -3
  76. package/dist/esm-node/commands/index.mjs +10 -2
  77. package/dist/esm-node/compat/hooks.mjs +1 -1
  78. package/dist/esm-node/esm/ts-paths-loader.mjs +5 -4
  79. package/dist/esm-node/index.mjs +10 -20
  80. package/dist/esm-node/plugins/analyze/getFileSystemEntry.mjs +1 -1
  81. package/dist/esm-node/plugins/analyze/getServerRoutes.mjs +1 -1
  82. package/dist/esm-node/plugins/analyze/index.mjs +2 -2
  83. package/dist/esm-node/plugins/analyze/utils.mjs +7 -7
  84. package/dist/esm-node/plugins/deploy/index.mjs +5 -21
  85. package/dist/esm-node/plugins/deploy/platforms/netlify.mjs +2 -1
  86. package/dist/esm-node/plugins/deploy/platforms/node.mjs +12 -3
  87. package/dist/esm-node/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  88. package/dist/esm-node/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  89. package/dist/esm-node/plugins/deploy/platforms/vercel.mjs +2 -1
  90. package/dist/esm-node/plugins/deploy/utils/index.mjs +17 -15
  91. package/dist/esm-node/plugins/initialize/index.mjs +6 -5
  92. package/dist/esm-node/plugins/serverBuild.mjs +0 -2
  93. package/dist/esm-node/run/index.mjs +5 -5
  94. package/dist/esm-node/types/config/base.mjs +2 -0
  95. package/dist/esm-node/types/plugin-base.mjs +1 -0
  96. package/dist/esm-node/types/plugin.mjs +1 -0
  97. package/dist/esm-node/utils/initAppContext.mjs +2 -2
  98. package/dist/esm-node/utils/loadPlugins.mjs +4 -8
  99. package/dist/esm-node/utils/register.mjs +1 -1
  100. package/dist/types/builder/generator/adapterCopy.d.ts +13 -1
  101. package/dist/types/builder/index.d.ts +1 -0
  102. package/dist/types/builder/shared/builderPlugins/adapterBasic.d.ts +4 -2
  103. package/dist/types/builder/shared/builderPlugins/adapterSSR.d.ts +2 -1
  104. package/dist/types/builder/shared/builderPlugins/builderHooks.d.ts +10 -2
  105. package/dist/types/builder/shared/lazyCompilation.d.ts +15 -0
  106. package/dist/types/compat/hooks.d.ts +3 -2
  107. package/dist/types/index.d.ts +1 -3
  108. package/dist/types/plugins/analyze/getBundleEntry.d.ts +5 -4
  109. package/dist/types/plugins/analyze/getFileSystemEntry.d.ts +5 -4
  110. package/dist/types/plugins/analyze/utils.d.ts +2 -2
  111. package/dist/types/plugins/deploy/index.d.ts +1 -4
  112. package/dist/types/plugins/deploy/utils/index.d.ts +1 -1
  113. package/dist/types/run/index.d.ts +1 -1
  114. package/dist/types/types/config/base.d.ts +58 -0
  115. package/dist/types/types/config/deploy.d.ts +2 -50
  116. package/dist/types/types/config/dev.d.ts +1 -1
  117. package/dist/types/types/config/index.d.ts +18 -42
  118. package/dist/types/types/config/output.d.ts +2 -2
  119. package/dist/types/types/config/testing.d.ts +1 -1
  120. package/dist/types/types/config/tools.d.ts +1 -1
  121. package/dist/types/types/plugin-base.d.ts +188 -0
  122. package/dist/types/types/plugin.d.ts +9 -183
  123. package/dist/types/utils/initAppContext.d.ts +1 -1
  124. package/docs/apis/app/commands.md +1 -0
  125. package/docs/configure/app/bff/effect.md +5 -12
  126. package/docs/configure/app/output/disable-svgr.md +4 -0
  127. package/docs/configure/app/output/svg-default-export.md +4 -0
  128. package/docs/configure/app/source/react-compiler.md +2 -0
  129. package/docs/configure/app/tools/less.md +94 -19
  130. package/docs/configure/app/tools/sass.md +87 -18
  131. package/docs/configure/app/tools/svgr.md +91 -0
  132. package/docs/configure/app/tools/ts-checker.md +7 -21
  133. package/docs/guides/basic-features/render/ssr-cache.md +14 -1
  134. package/docs/guides/basic-features/static-assets/svg-assets.md +29 -17
  135. package/docs/guides/basic-features/testing/rstest.md +0 -2
  136. package/docs/guides/get-started/quick-start.md +1 -1
  137. package/docs/guides/get-started/ultramodern.md +45 -14
  138. package/docs/llms.txt +4 -3
  139. package/docs/plugin/introduction.md +10 -10
  140. package/docs/plugin/server-plugins/api.md +1 -0
  141. package/package.json +59 -30
  142. package/dist/cjs/plugins/serverRuntime.js +0 -53
  143. package/dist/esm/plugins/serverRuntime.mjs +0 -15
  144. package/dist/esm-node/plugins/serverRuntime.mjs +0 -16
  145. package/dist/types/plugins/serverRuntime.d.ts +0 -3
@@ -1,10 +1,10 @@
1
- import __rslib_shim_module__ from "node:module";
2
- const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
1
+ import "node:module";
2
+ import { resolveDeployTarget } from "@modern-js/app-tools-extensions/deploy-output/target";
3
3
  import { createPolicyDefaultsPlugin } from "@modern-js/app-tools-extensions/policy-defaults";
4
4
  import { castArray } from "@modern-js/builder";
5
5
  import { getLocaleLanguage } from "@modern-js/i18n-utils/language-detector";
6
6
  import { createAsyncHook } from "@modern-js/plugin";
7
- import { cleanRequireCache, deprecatedCommands, emptyDir, getArgv, getCommand } from "@modern-js/utils";
7
+ import { deprecatedCommands, emptyDir, getArgv, getCommand } from "@modern-js/utils";
8
8
  import path from "path";
9
9
  import { buildCommand, deployCommand, devCommand, infoCommand, inspectCommand, serverCommand } from "./commands/index.mjs";
10
10
  import { compatPlugin } from "./compat/index.mjs";
@@ -14,7 +14,6 @@ import analyze from "./plugins/analyze/index.mjs";
14
14
  import deploy from "./plugins/deploy/index.mjs";
15
15
  import initialize from "./plugins/initialize/index.mjs";
16
16
  import serverBuild from "./plugins/serverBuild.mjs";
17
- import serverRuntime from "./plugins/serverRuntime.mjs";
18
17
  import { generateWatchFiles } from "./utils/generateWatchFiles.mjs";
19
18
  import { initAppContext } from "./utils/initAppContext.mjs";
20
19
  import { restart } from "./utils/restart.mjs";
@@ -23,7 +22,6 @@ export * from "./types/index.mjs";
23
22
  const appTools = (options = {})=>({
24
23
  name: '@modern-js/app-tools',
25
24
  usePlugins: [
26
- serverRuntime(),
27
25
  compatPlugin(),
28
26
  initialize(),
29
27
  analyze(),
@@ -76,6 +74,11 @@ const appTools = (options = {})=>({
76
74
  deprecatedCommands(program);
77
75
  });
78
76
  api.onPrepare(async ()=>{
77
+ api.updateAppContext({
78
+ deployTarget: resolveDeployTarget({
79
+ configTarget: api.getNormalizedConfig().deploy?.target
80
+ })
81
+ });
79
82
  const command = getCommand();
80
83
  if ('deploy' === command) {
81
84
  const isSkipBuild = [
@@ -84,18 +87,12 @@ const appTools = (options = {})=>({
84
87
  ].some((tag)=>getArgv().includes(tag));
85
88
  if (isSkipBuild) return;
86
89
  }
87
- const { command: contextCommand } = api.getAppContext();
88
- const shouldClean = [
90
+ if ([
89
91
  'dev',
90
92
  'start',
91
93
  'build',
92
94
  'deploy'
93
- ].includes(command) || [
94
- 'dev',
95
- 'start',
96
- 'build'
97
- ].includes(contextCommand);
98
- if (shouldClean) {
95
+ ].includes(command)) {
99
96
  const resolvedConfig = api.getNormalizedConfig();
100
97
  if (resolvedConfig.output.cleanDistPath) {
101
98
  const appContext = api.getAppContext();
@@ -126,17 +123,10 @@ const appTools = (options = {})=>({
126
123
  await restart(api.getHooks(), filename);
127
124
  }
128
125
  });
129
- api.onBeforeRestart(()=>{
130
- cleanRequireCache([
131
- require.resolve('./plugins/analyze')
132
- ]);
133
- });
134
126
  }
135
127
  });
136
128
  const src = appTools;
137
129
  export { defineConfig } from "./defineConfig.mjs";
138
- export { build } from "./commands/build.mjs";
139
- export { deploy } from "./commands/deploy.mjs";
140
130
  export { dev } from "./commands/dev.mjs";
141
131
  export { serve } from "./commands/serve.mjs";
142
132
  export { resolveModernRsbuildConfig } from "./rsbuild.mjs";
@@ -62,6 +62,6 @@ const getFileSystemEntry = async (hooks, appContext, config)=>{
62
62
  }));
63
63
  return scanDir(hooks, dirs);
64
64
  } else throw Error("source.entriesDir accept a directory.");
65
- throw Error(`src dir ${entriesDir} not found.`);
65
+ else throw Error(`src dir ${entriesDir} not found.`);
66
66
  };
67
67
  export { getFileSystemEntry, hasEntry, hasServerEntry };
@@ -27,7 +27,7 @@ const applyRouteOptions = (original, routeOptions)=>{
27
27
  ...original,
28
28
  urlPath: url
29
29
  };
30
- {
30
+ else {
31
31
  const { path: urlPath, ...other } = url;
32
32
  return {
33
33
  ...original,
@@ -24,7 +24,7 @@ const analyze = ()=>({
24
24
  const resolvedConfig = api.getNormalizedConfig();
25
25
  const hooks = api.getHooks();
26
26
  try {
27
- if (checkIsBuildCommands(appContext.command)) fs.emptydirSync(appContext.internalDirectory);
27
+ if (checkIsBuildCommands()) fs.emptydirSync(appContext.internalDirectory);
28
28
  } catch {}
29
29
  const apiOnly = await isApiOnly(appContext.appDirectory, resolvedConfig.source?.entriesDir, appContext.apiDirectory);
30
30
  const [{ getProdEntrypoints, getProdServerRoutes }] = await Promise.all([
@@ -126,7 +126,7 @@ const analyze = ()=>({
126
126
  htmlTemplates
127
127
  };
128
128
  api.updateAppContext(appContext);
129
- if (checkIsBuildCommands(appContext.command)) {
129
+ if (checkIsBuildCommands()) {
130
130
  await hooks.generateEntryCode.call({
131
131
  entrypoints
132
132
  });
@@ -1,6 +1,6 @@
1
1
  import "node:module";
2
2
  import { JS_EXTENSIONS, getCommand, normalizeToPosixPath } from "@modern-js/utils";
3
- import { parse } from "es-module-lexer";
3
+ import { init, parse } from "es-module-lexer";
4
4
  import { transform } from "esbuild";
5
5
  import fs from "fs";
6
6
  import path from "path";
@@ -10,14 +10,14 @@ const walkDirectory = (dir)=>fs.readdirSync(dir).reduce((previous, filename)=>{
10
10
  ...previous,
11
11
  ...walkDirectory(filePath)
12
12
  ];
13
- return [
13
+ else return [
14
14
  ...previous,
15
15
  filePath
16
16
  ];
17
17
  }, []);
18
18
  const replaceWithAlias = (base, filePath, alias)=>{
19
19
  if (filePath.includes(base)) return normalizeToPosixPath(path.join(alias, path.relative(base, filePath)));
20
- return filePath;
20
+ else return filePath;
21
21
  };
22
22
  const parseModule = async ({ source, filename })=>{
23
23
  let content = source;
@@ -36,10 +36,11 @@ const parseModule = async ({ source, filename })=>{
36
36
  });
37
37
  content = result.code;
38
38
  }
39
- return await parse(content);
39
+ await init();
40
+ return parse(content);
40
41
  };
41
42
  const getServerCombinedModuleFile = (internalDirectory, entryName)=>path.join(internalDirectory, entryName, 'server-loader-combined.js');
42
- const checkIsBuildCommands = (contextCommand)=>{
43
+ const checkIsBuildCommands = ()=>{
43
44
  const buildCommands = [
44
45
  'dev',
45
46
  'start',
@@ -49,8 +50,7 @@ const checkIsBuildCommands = (contextCommand)=>{
49
50
  'dev-worker'
50
51
  ];
51
52
  const command = getCommand();
52
- if (buildCommands.includes(command)) return true;
53
- return 'dev' === contextCommand || 'start' === contextCommand || 'build' === contextCommand || 'deploy' === contextCommand;
53
+ return buildCommands.includes(command);
54
54
  };
55
55
  const checkIsServeCommand = ()=>{
56
56
  const command = getCommand();
@@ -1,6 +1,6 @@
1
1
  import "node:module";
2
2
  import { createCloudflarePreset } from "@modern-js/app-tools-extensions/cloudflare";
3
- import { provider } from "std-env";
3
+ import { getDeployingTarget } from "@modern-js/app-tools-extensions/deploy-output/target";
4
4
  import { createGhPagesPreset } from "./platforms/gh-pages.mjs";
5
5
  import { createNetlifyPreset } from "./platforms/netlify.mjs";
6
6
  import { createNodePreset } from "./platforms/node.mjs";
@@ -13,24 +13,11 @@ const deployPresets = {
13
13
  ghPages: createGhPagesPreset,
14
14
  cloudflare: createCloudflarePreset
15
15
  };
16
- const getSupportedDeployTargets = ()=>Object.keys(deployPresets);
17
- const isDeployTarget = (target)=>Object.prototype.hasOwnProperty.call(deployPresets, target);
18
- const providerDeployTargets = {
19
- vercel: 'vercel',
20
- netlify: 'netlify',
21
- cloudflare: 'cloudflare',
22
- cloudflare_pages: 'cloudflare',
23
- cloudflare_workers: 'cloudflare'
24
- };
25
- const normalizeDetectedProvider = (value)=>value ? providerDeployTargets[value] : void 0;
26
- const resolveDeployTarget = (modernConfig, envDeployTarget = process.env.MODERNJS_DEPLOY, detectedProvider = provider)=>modernConfig.deploy?.target || envDeployTarget || normalizeDetectedProvider(detectedProvider) || 'node';
27
16
  async function getDeployPreset(appContext, modernConfig, deployTarget, api) {
28
17
  const { appDirectory, distDirectory, metaName } = appContext;
29
18
  const { useSSR, useAPI, useWebServer } = getProjectUsage(appDirectory, distDirectory, metaName);
30
19
  const needModernServer = useSSR || useAPI || useWebServer;
31
- if (!isDeployTarget(deployTarget)) throw new Error(`Unknown deploy target: '${deployTarget}'. deploy.target or MODERNJS_DEPLOY should be one of: ${getSupportedDeployTargets().join(', ')}.`);
32
- const createPreset = deployPresets[deployTarget];
33
- return createPreset({
20
+ return deployPresets[deployTarget]({
34
21
  appContext,
35
22
  modernConfig,
36
23
  needModernServer,
@@ -42,11 +29,9 @@ const deploy = ()=>({
42
29
  setup: (api)=>{
43
30
  api.deploy(async ()=>{
44
31
  const appContext = api.getAppContext();
45
- const { metaName } = appContext;
46
- const modernConfig = api.getNormalizedConfig();
47
- const deployTarget = resolveDeployTarget(modernConfig);
48
- if ('modern-js' !== metaName && !modernConfig.deploy?.target && !process.env.MODERNJS_DEPLOY) return;
49
- const deployPreset = await getDeployPreset(appContext, modernConfig, deployTarget, api);
32
+ const deployTarget = getDeployingTarget(appContext);
33
+ if (!deployTarget) return;
34
+ const deployPreset = await getDeployPreset(appContext, api.getNormalizedConfig(), deployTarget, api);
50
35
  deployPreset?.prepare && await deployPreset?.prepare();
51
36
  deployPreset?.writeOutput && await deployPreset?.writeOutput();
52
37
  deployPreset?.genEntry && await deployPreset?.genEntry();
@@ -55,4 +40,3 @@ const deploy = ()=>({
55
40
  }
56
41
  });
57
42
  export default deploy;
58
- export { getSupportedDeployTargets, resolveDeployTarget };
@@ -1,6 +1,7 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
3
  import node_path from "node:path";
4
+ import { traceDeployFiles } from "@modern-js/app-tools-extensions/deploy-output/trace-files";
4
5
  import { fs, removeModuleSyncFromExports } from "@modern-js/utils";
5
6
  import { nodeDepEmit } from "ndepe";
6
7
  import { isMainEntry } from "../../../utils/routes.mjs";
@@ -73,8 +74,8 @@ const createNetlifyPreset = ({ appContext, modernConfig, needModernServer })=>{
73
74
  if (!needModernServer) return;
74
75
  const entry = isEsmProject ? await resolveESMDependency('@modern-js/prod-server') : require.resolve('@modern-js/prod-server');
75
76
  const netlifyEntry = isEsmProject ? await resolveESMDependency('@modern-js/prod-server/netlify') : require.resolve('@modern-js/prod-server/netlify');
76
- if (!entry || !netlifyEntry) throw new Error('Cannot find @modern-js/prod-server');
77
77
  await nodeDepEmit({
78
+ traceFiles: traceDeployFiles,
78
79
  appDir: appDirectory,
79
80
  sourceDir: funcsDirectory,
80
81
  includeEntries: [
@@ -1,12 +1,14 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
+ import { createRequire } from "node:module";
3
4
  import node_path from "node:path";
5
+ import { traceDeployFiles } from "@modern-js/app-tools-extensions/deploy-output/trace-files";
4
6
  import { chalk, fs, removeModuleSyncFromExports } from "@modern-js/utils";
5
7
  import { nodeDepEmit } from "ndepe";
6
8
  import { readTemplate, resolveESMDependency } from "../utils/index.mjs";
7
9
  import { generateHandler } from "../utils/generator.mjs";
8
10
  const createNodePreset = ({ appContext, modernConfig })=>{
9
- const { appDirectory, distDirectory, moduleType } = appContext;
11
+ const { appDirectory, distDirectory, moduleType, serverPlugins } = appContext;
10
12
  const isEsmProject = 'module' === moduleType;
11
13
  const outputDirectory = node_path.join(appDirectory, '.output');
12
14
  const staticDirectory = node_path.join(outputDirectory, 'static');
@@ -36,12 +38,19 @@ const createNodePreset = ({ appContext, modernConfig })=>{
36
38
  async end () {
37
39
  const filter = (filePath)=>!filePath.startsWith(staticDirectory) && !filePath.endsWith('.map');
38
40
  const entry = isEsmProject ? await resolveESMDependency('@modern-js/prod-server') : require.resolve('@modern-js/prod-server');
39
- if (!entry) throw new Error('Cannot find @modern-js/prod-server');
41
+ const requireFromApp = createRequire(node_path.join(appDirectory, 'package.json'));
42
+ const pluginEntries = new Set();
43
+ for (const plugin of serverPlugins)for (const specifier of plugin.includeEntries ?? []){
44
+ pluginEntries.add(requireFromApp.resolve(specifier));
45
+ if (isEsmProject) pluginEntries.add(await resolveESMDependency(specifier, appDirectory));
46
+ }
40
47
  await nodeDepEmit({
48
+ traceFiles: traceDeployFiles,
41
49
  appDir: appDirectory,
42
50
  sourceDir: outputDirectory,
43
51
  includeEntries: [
44
- entry
52
+ entry,
53
+ ...pluginEntries
45
54
  ],
46
55
  copyWholePackage (pkgName) {
47
56
  return '@modern-js/utils' === pkgName;
@@ -35,10 +35,11 @@ async function main() {
35
35
  const app = await createProdServer(prodServerOptions);
36
36
  const port = process.env.PORT || 8080;
37
37
  app.listen({
38
- host: '::',
39
38
  port
40
39
  }, ()=>{
41
- console.log(`\x1b[32mServer is listening on http://[::]:${port}`, '\x1b[0m');
40
+ const address = app.address();
41
+ const loopback = 'IPv6' === address.family ? '[::1]' : '127.0.0.1';
42
+ console.log(`\x1b[32mServer is listening on http://${loopback}:${address.port}`, '\x1b[0m');
42
43
  });
43
44
  }
44
45
  main();
@@ -37,10 +37,11 @@ async function main() {
37
37
  const app = await createProdServer(prodServerOptions);
38
38
  const port = process.env.PORT || 8080;
39
39
  app.listen({
40
- host: '::',
41
40
  port
42
41
  }, ()=>{
43
- console.log(`\x1b[32mServer is listening on http://[::]:${port}`, '\x1b[0m');
42
+ const address = app.address();
43
+ const loopback = 'IPv6' === address.family ? '[::1]' : '127.0.0.1';
44
+ console.log(`\x1b[32mServer is listening on http://${loopback}:${address.port}`, '\x1b[0m');
44
45
  });
45
46
  }
46
47
  main();
@@ -1,6 +1,7 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
3
  import node_path from "node:path";
4
+ import { traceDeployFiles } from "@modern-js/app-tools-extensions/deploy-output/trace-files";
4
5
  import { fs, removeModuleSyncFromExports } from "@modern-js/utils";
5
6
  import { nodeDepEmit } from "ndepe";
6
7
  import { isMainEntry } from "../../../utils/routes.mjs";
@@ -93,8 +94,8 @@ const createVercelPreset = ({ appContext, modernConfig, needModernServer })=>{
93
94
  async end () {
94
95
  if (!needModernServer) return;
95
96
  const entry = isEsmProject ? await resolveESMDependency('@modern-js/prod-server') : require.resolve('@modern-js/prod-server');
96
- if (!entry) throw new Error('Cannot find @modern-js/prod-server');
97
97
  await nodeDepEmit({
98
+ traceFiles: traceDeployFiles,
98
99
  appDir: appDirectory,
99
100
  sourceDir: funcsDirectory,
100
101
  includeEntries: [
@@ -1,12 +1,11 @@
1
1
  import "node:module";
2
- import { createRequire } from "node:module";
3
- import { pathToFileURL } from "node:url";
4
- import { ROUTE_SPEC_FILE, SERVER_DIR, dynamicImport, fs, getMeta } from "@modern-js/utils";
2
+ import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import { ROUTE_SPEC_FILE, SERVER_DIR, fs, getMeta } from "@modern-js/utils";
4
+ import { moduleResolve } from "import-meta-resolve";
5
5
  import path from "path";
6
6
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
7
7
  import { dirname as __rspack_dirname } from "node:path";
8
8
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
9
- var __rspack_import_meta_filename__ = __rspack_fileURLToPath(import.meta.url);
10
9
  const normalizePath = (filePath)=>filePath.replace(/\\/g, '/');
11
10
  const getProjectUsage = (appDirectory, distDirectory, metaName)=>{
12
11
  const routeJSON = path.join(distDirectory, ROUTE_SPEC_FILE);
@@ -31,17 +30,20 @@ const getProjectUsage = (appDirectory, distDirectory, metaName)=>{
31
30
  };
32
31
  const getTemplatePath = (file)=>path.join(__rspack_import_meta_dirname__, '../platforms/templates', file);
33
32
  const readTemplate = async (file)=>(await fs.readFile(getTemplatePath(file))).toString();
34
- const resolveESMDependency = async (entry)=>{
35
- const conditions = new Set([
36
- 'node',
37
- 'import',
38
- 'module',
39
- 'default'
40
- ]);
33
+ const DEPLOY_CONDITIONS = [
34
+ 'node',
35
+ 'import',
36
+ 'module',
37
+ 'default'
38
+ ];
39
+ const resolveESMDependency = async (entry, fromDirectory)=>{
40
+ const base = fromDirectory ? pathToFileURL(path.join(fromDirectory, 'package.json')) : pathToFileURL(`${__rspack_import_meta_dirname__}/`);
41
41
  try {
42
- const resolverPath = pathToFileURL(createRequire(__rspack_import_meta_filename__).resolve('import-meta-resolve')).href;
43
- const { moduleResolve } = await dynamicImport(resolverPath);
44
- return normalizePath(moduleResolve(entry, pathToFileURL(`${__rspack_import_meta_dirname__}/`), conditions, false).pathname.replace(/^\/(\w):/, '$1:'));
45
- } catch (err) {}
42
+ return normalizePath(fileURLToPath(moduleResolve(entry, base, new Set(DEPLOY_CONDITIONS), false)));
43
+ } catch (cause) {
44
+ throw new Error(`Cannot resolve "${entry}" with conditions [${DEPLOY_CONDITIONS.join(', ')}] from ${base.href}: ${cause.message}`, {
45
+ cause
46
+ });
47
+ }
46
48
  };
47
49
  export { getProjectUsage, getTemplatePath, normalizePath, readTemplate, resolveESMDependency };
@@ -1,5 +1,6 @@
1
1
  import "node:module";
2
2
  import { ensureAbsolutePath, getPort, isDev, isDevCommand } from "@modern-js/utils";
3
+ import { buildDefaultLazyCompilationTest } from "../../builder/shared/lazyCompilation.mjs";
3
4
  import { createDefaultConfig, isLazyCompilationSafeByDefault } from "../../config/index.mjs";
4
5
  const initialize = ()=>({
5
6
  name: '@modern-js/plugin-initialize',
@@ -18,7 +19,8 @@ const initialize = ()=>({
18
19
  ...defaultConfig.dev,
19
20
  lazyCompilation: {
20
21
  imports: true,
21
- entries: false
22
+ entries: false,
23
+ test: buildDefaultLazyCompilationTest(appContext.appDirectory, appContext.internalDirectory)
22
24
  }
23
25
  };
24
26
  return defaultConfig;
@@ -26,7 +28,7 @@ const initialize = ()=>({
26
28
  api.modifyResolvedConfig(async (resolved)=>{
27
29
  let appContext = api.getAppContext();
28
30
  const userConfig = api.getConfig();
29
- const port = await getServerPort(resolved, appContext.command);
31
+ const port = await getServerPort(resolved);
30
32
  appContext = {
31
33
  ...appContext,
32
34
  port,
@@ -61,10 +63,9 @@ function stabilizeConfig(resolve, config, keys) {
61
63
  resolve[key] = config[key] || {};
62
64
  });
63
65
  }
64
- async function getServerPort(config, contextCommand) {
66
+ async function getServerPort(config) {
65
67
  const prodPort = Number(process.env.PORT) || config.server.port || 8080;
66
- const isProgrammaticDev = 'dev' === contextCommand || 'start' === contextCommand;
67
- if (isDev() && (isDevCommand() || isProgrammaticDev)) return getPort(Number(process.env.PORT) || prodPort);
68
+ if (isDev() && isDevCommand()) return getPort(Number(process.env.PORT) || prodPort);
68
69
  return prodPort;
69
70
  }
70
71
  export default initialize;
@@ -30,10 +30,8 @@ const serverBuild = ()=>({
30
30
  sourceDirs.push(serverDir);
31
31
  if (fs.existsSync(sharedDir)) sourceDirs.push(sharedDir);
32
32
  }
33
- const { server } = modernConfig;
34
33
  const { alias } = modernConfig.source;
35
34
  if (sourceDirs.length > 0) await compile(appDirectory, {
36
- server,
37
35
  alias
38
36
  }, {
39
37
  sourceDirs,
@@ -8,21 +8,21 @@ import { loadInternalPlugins } from "../utils/loadPlugins.mjs";
8
8
  async function createRunOptions({ cwd, initialLog, metaName = 'modern-js', version, internalPlugins, configFile }) {
9
9
  const nodeVersion = process.versions.node;
10
10
  const versionArr = nodeVersion.split('.').map(Number);
11
- if (versionArr[0] < 26 || 26 === versionArr[0] && versionArr[1] < 7) throw new Error(`
11
+ if (versionArr[0] < 26 || 26 === versionArr[0] && versionArr[1] < 10) throw new Error(`
12
12
  ${chalk.bgRed.white.bold(' UNSUPPORTED NODE.JS RUNTIME ')}
13
13
 
14
- ${chalk.red.bold(`UltraModern.js requires Node.js >=26.7.0; detected v${nodeVersion}.`)}
14
+ ${chalk.red.bold(`UltraModern.js requires Node.js >=26.10.0; detected v${nodeVersion}.`)}
15
15
  ${chalk.red('- Legacy Node runtimes and TypeScript transpiler fallbacks are unsupported.')}
16
16
 
17
17
  ${chalk.yellow('▸ Detected Runtime:')} ${chalk.yellow.bold(`Node.js v${nodeVersion}`)}
18
- ${chalk.green('▸ Required Minimum:')} ${chalk.green.bold('Node.js v26.7.0 or higher')}
19
- ${chalk.green('▸ Pinned Runtime:')} ${chalk.green.bold('Node.js v26.7.0')}
18
+ ${chalk.green('▸ Required Minimum:')} ${chalk.green.bold('Node.js v26.10.0 or higher')}
19
+ ${chalk.green('▸ Pinned Runtime:')} ${chalk.green.bold('Node.js v26.10.0')}
20
20
 
21
21
  ${chalk.cyan('Immediate Action Required:')}
22
22
  ${chalk.gray('├──')} ${chalk.yellow('Recommended Upgrade')}
23
23
  ${chalk.bold('mise install && mise exec -- node --version')}
24
24
  ${chalk.gray('├──')} ${chalk.yellow('Manual Installation')}
25
- ${chalk.underline('https://nodejs.org/download/release/v26.7.0/')}
25
+ ${chalk.underline('https://nodejs.org/download/release/v26.10.0/')}
26
26
  ${chalk.gray('└──')} ${chalk.yellow('Environment Verification')}
27
27
  ${chalk.bold('node -v && npm -v')}
28
28
 
@@ -0,0 +1,2 @@
1
+ import "node:module";
2
+ export * from "./output.mjs";
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -1 +1,2 @@
1
1
  import "node:module";
2
+ export * from "./plugin-base.mjs";
@@ -1,5 +1,5 @@
1
1
  import "node:module";
2
- import { address, fs } from "@modern-js/utils";
2
+ import { fs, ip } from "@modern-js/utils";
3
3
  import path from "path";
4
4
  function isSymlinkedNodeModules(appDirectory) {
5
5
  try {
@@ -18,7 +18,7 @@ const initAppContext = ({ metaName, appDirectory, runtimeConfigFile, options, te
18
18
  const moduleType = fs.existsSync(pkgPath) ? fs.readJSONSync(pkgPath).type || 'commonjs' : 'commonjs';
19
19
  return {
20
20
  runtimeConfigFile,
21
- ip: address.ip(),
21
+ ip: ip(),
22
22
  port: 0,
23
23
  moduleType,
24
24
  apiDirectory: path.resolve(appDirectory, apiDir),
@@ -1,13 +1,14 @@
1
1
  import "node:module";
2
+ import node_path from "node:path";
2
3
  import { loadServerPlugins } from "@modern-js/server-core/node";
3
- import { compatibleRequire, createDebugger, dynamicImport, getInternalPlugins, tryResolve } from "@modern-js/utils";
4
+ import { compatibleRequire, createDebugger, getInternalPlugins, tryResolve } from "@modern-js/utils";
4
5
  const debug = createDebugger('load-plugins');
5
6
  async function getServerPlugins(api, metaName = 'modern-js') {
6
7
  const hooks = api.getHooks();
7
8
  const { plugins } = await hooks._internalServerPlugins.call({
8
9
  plugins: []
9
10
  });
10
- const filtedPlugins = plugins.filter((plugin)=>plugin.name.includes(metaName));
11
+ const filtedPlugins = plugins.filter((plugin)=>node_path.isAbsolute(plugin.name) || plugin.name.includes(metaName));
11
12
  api.updateAppContext({
12
13
  serverPlugins: filtedPlugins
13
14
  });
@@ -22,12 +23,7 @@ const resolveCliPlugin = async (p, appDirectory)=>{
22
23
  const pkg = 'string' == typeof p ? p : p[0];
23
24
  const pluginOptions = 'string' == typeof p ? void 0 : p[1];
24
25
  const path = tryResolve(pkg, appDirectory);
25
- let module;
26
- try {
27
- module = await compatibleRequire(path);
28
- } catch (e) {
29
- ({ default: module } = await dynamicImport(path));
30
- }
26
+ const module = await compatibleRequire(path);
31
27
  if ('function' == typeof module) {
32
28
  const result = module(pluginOptions);
33
29
  return result;
@@ -59,7 +59,7 @@ const resolveTsRuntimeRegisterMode = ()=>{
59
59
  return 'unsupported';
60
60
  };
61
61
  const setupTsRuntime = async (appDir, distDir, alias, options = {})=>{
62
- if ('unsupported' === resolveTsRuntimeRegisterMode()) throw new Error(`UltraModern.js requires Node.js >=26.7.0 with native TypeScript support; detected v${process.versions.node}. Legacy TypeScript runtime transpilers are unsupported.`);
62
+ if ('unsupported' === resolveTsRuntimeRegisterMode()) throw new Error(`UltraModern.js requires Node.js >=26.10.0 with native TypeScript support; detected v${process.versions.node}. Legacy TypeScript runtime transpilers are unsupported.`);
63
63
  const tsconfigPath = resolveServerTsconfig(appDir, options.tsconfigPath);
64
64
  const isTsProject = await fs.pathExists(tsconfigPath);
65
65
  if (!isTsProject) return;
@@ -1,3 +1,15 @@
1
- import type { RsbuildPlugin } from '@modern-js/builder';
1
+ import type { RsbuildPlugin, Rspack } from '@modern-js/builder';
2
2
  import type { BuilderOptions } from '../shared/index.js';
3
+ /**
4
+ * The copy plugin registers each pattern context as a context dependency even
5
+ * when the directory is absent. The watcher reports an absent context as
6
+ * removed right after the first build, which rebuilds every dev session once.
7
+ * Watch an absent context, and its absent parents, as missing instead: their
8
+ * later creation still rebuilds and copies.
9
+ */
10
+ export declare class MissingCopyContextPlugin {
11
+ private readonly contexts;
12
+ constructor(contexts: readonly string[]);
13
+ apply(compiler: Rspack.Compiler): void;
14
+ }
3
15
  export declare const builderPluginAdapterCopy: (options: BuilderOptions) => RsbuildPlugin;
@@ -1,3 +1,4 @@
1
1
  export declare function createBuilderGenerator(): Promise<typeof import("./builder-rspack/index.js").createRspackBuilderForModern>;
2
2
  export { parseRspackConfig } from '@modern-js/builder';
3
+ export { getBundleEntry } from '../plugins/analyze/getBundleEntry.js';
3
4
  export { builderPluginAdapterBasic, builderPluginAdapterHooks, } from './shared/builderPlugins/index.js';
@@ -1,3 +1,5 @@
1
+ import type { AppContext, CLIPluginExtends } from '@modern-js/plugin/cli';
1
2
  import type { RsbuildPlugin } from '@rsbuild/core';
2
- import type { BuilderOptions } from '../types.js';
3
- export declare const builderPluginAdapterBasic: (options: BuilderOptions) => RsbuildPlugin;
3
+ export declare const builderPluginAdapterBasic: <Options extends {
4
+ appContext: Pick<AppContext<CLIPluginExtends>, 'metaName'>;
5
+ }>(options: Options) => RsbuildPlugin;
@@ -1,5 +1,5 @@
1
1
  import { type Rspack } from '@modern-js/builder';
2
- import { type RsbuildPlugin } from '@rsbuild/core';
2
+ import { type RsbuildPlugin, type RspackChain } from '@rsbuild/core';
3
3
  import type { AppNormalizedConfig } from '../../../types/index.js';
4
4
  import type { AppToolsContext } from '../../../types/plugin.js';
5
5
  import type { BuilderOptions } from '../types.js';
@@ -12,3 +12,4 @@ export declare const builderPluginAdapterSSR: (options: BuilderOptions) => Rsbui
12
12
  * so the caller leaves the config untouched.
13
13
  */
14
14
  export declare function getSSRLazyCompilation(current: unknown, normalizedConfig: AppNormalizedConfig, appContext: AppToolsContext, eagerRouteComponentFilesByEntry: BuilderOptions['eagerRouteComponentFilesByEntry']): Rspack.LazyCompilationOptions | undefined;
15
+ export declare function applySSRLoaderEntry(chain: RspackChain, optinos: BuilderOptions, isServer: boolean, isServiceWorker: boolean): Promise<void>;
@@ -1,3 +1,11 @@
1
+ import type { Hooks } from '@modern-js/plugin/cli';
1
2
  import type { RsbuildPlugin } from '@rsbuild/core';
2
- import type { BuilderOptions } from '../types.js';
3
- export declare const builderPluginAdapterHooks: (options: BuilderOptions) => RsbuildPlugin;
3
+ export declare const builderPluginAdapterHooks: <Options extends {
4
+ appContext: {
5
+ _internalContext: {
6
+ pluginAPI?: {
7
+ getHooks(): Readonly<Pick<Hooks<{}, {}, {}, {}>, 'modifyBundlerChain' | 'modifyRsbuildConfig' | 'modifyRspackConfig'>>;
8
+ };
9
+ };
10
+ };
11
+ }>(options: Options) => RsbuildPlugin;
@@ -26,6 +26,21 @@ export declare function aggregateEagerRouteComponentFiles(byEntry: EagerRouteCom
26
26
  * (defaulting to lazy when the user did not provide one).
27
27
  */
28
28
  export declare function buildSSRLazyCompilationTest(eagerRouteFiles: Set<string>, userTest?: LazyCompilationTest): LazyCompilationTestFn;
29
+ /**
30
+ * Build the default dev `lazyCompilation.test`: a dynamic import is lazy only
31
+ * when it targets the app's own source. Everything else compiles eagerly:
32
+ * - the generated `<internalDirectory>/<entry>/index.jsx`, which
33
+ * `bootstrap.jsx` imports as the async entry boundary Module Federation
34
+ * needs to initialize shared scopes, not a code-split point;
35
+ * - framework and dependency modules (outside `appDirectory` or under
36
+ * `node_modules`), such as plugin-i18n's backend, utils and react-i18next.
37
+ * Each lazy module costs one on-demand compile and HMR cycle on the first page
38
+ * load. Back-to-back cycles for framework imports raced on loaded CI runners
39
+ * ("Cannot read properties of undefined (reading 'call')"), and the app never
40
+ * rendered.
41
+ * Typed `object` so it is assignable to Rspack's `(module: Module) => boolean`.
42
+ */
43
+ export declare function buildDefaultLazyCompilationTest(appDirectory: string, internalDirectory: string): (m: object) => boolean;
29
44
  export type SSRLazyPlan = {
30
45
  apply: false;
31
46
  unresolvedByEntry?: Map<string, string[]>;
@@ -1,7 +1,8 @@
1
1
  import type { InternalContext } from '@modern-js/plugin';
2
- import type { AppTools } from '../types/index.js';
2
+ import type { AppTools } from '../types/config/index.js';
3
+ import type { AppToolsHookRunners } from '../types/plugin-base.js';
3
4
  /**
4
5
  * old plugin useHookRunners function result
5
6
  */
6
- export declare function getHookRunners(context: InternalContext<AppTools>): Record<string, any>;
7
+ export declare function getHookRunners(context: InternalContext<AppTools>): AppToolsHookRunners;
7
8
  export declare function handleSetupResult(setupResult: Record<string, (...args: any) => any>, api: Record<string, any>): void;