@modern-js/app-tools 3.1.1 → 3.1.3

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 (38) hide show
  1. package/dist/cjs/commands/build.js +3 -9
  2. package/dist/cjs/commands/dev.js +4 -9
  3. package/dist/cjs/esm/register-esm.js +16 -12
  4. package/dist/cjs/esm/register-esm.mjs +11 -10
  5. package/dist/cjs/esm/ts-paths-loader.js +95 -0
  6. package/dist/cjs/esm/ts-paths-loader.mjs +57 -0
  7. package/dist/cjs/plugins/analyze/utils.js +6 -1
  8. package/dist/cjs/utils/register.js +48 -17
  9. package/dist/esm/builder/shared/builderPlugins/adapterSSR.mjs +2 -2
  10. package/dist/esm/commands/build.mjs +3 -9
  11. package/dist/esm/commands/dev.mjs +4 -9
  12. package/dist/esm/esm/register-esm.mjs +12 -11
  13. package/dist/esm/esm/ts-paths-loader.mjs +58 -0
  14. package/dist/esm/index.mjs +2 -2
  15. package/dist/esm/plugins/analyze/getHtmlTemplate.mjs +2 -2
  16. package/dist/esm/plugins/analyze/index.mjs +3 -3
  17. package/dist/esm/plugins/analyze/isDefaultExportFunction.mjs +2 -2
  18. package/dist/esm/plugins/analyze/utils.mjs +6 -1
  19. package/dist/esm/utils/config.mjs +2 -2
  20. package/dist/esm/utils/register.mjs +45 -17
  21. package/dist/esm-node/builder/shared/builderPlugins/adapterBasic.mjs +2 -2
  22. package/dist/esm-node/builder/shared/builderPlugins/adapterSSR.mjs +2 -2
  23. package/dist/esm-node/commands/build.mjs +3 -9
  24. package/dist/esm-node/commands/dev.mjs +4 -9
  25. package/dist/esm-node/esm/register-esm.mjs +12 -11
  26. package/dist/esm-node/esm/ts-paths-loader.mjs +59 -0
  27. package/dist/esm-node/index.mjs +2 -2
  28. package/dist/esm-node/plugins/analyze/getHtmlTemplate.mjs +2 -2
  29. package/dist/esm-node/plugins/analyze/index.mjs +3 -3
  30. package/dist/esm-node/plugins/analyze/isDefaultExportFunction.mjs +2 -2
  31. package/dist/esm-node/plugins/analyze/utils.mjs +6 -1
  32. package/dist/esm-node/plugins/deploy/utils/index.mjs +2 -2
  33. package/dist/esm-node/utils/config.mjs +2 -2
  34. package/dist/esm-node/utils/register.mjs +45 -17
  35. package/dist/types/esm/register-esm.d.mts +5 -0
  36. package/dist/types/esm/ts-paths-loader.d.mts +6 -0
  37. package/dist/types/utils/register.d.ts +8 -1
  38. package/package.json +15 -15
@@ -70,15 +70,9 @@ const build = async (api, options)=>{
70
70
  const hooks = api.getHooks();
71
71
  const combinedAlias = [].concat(resolvedConfig?.resolve?.alias ?? []).concat(resolvedConfig?.source?.alias ?? []);
72
72
  await (0, loadPlugins_js_namespaceObject.loadServerPlugins)(api, appContext.appDirectory, appContext.metaName);
73
- if (appContext.moduleType && 'module' === appContext.moduleType) {
74
- const { registerModuleHooks } = await import("../esm/register-esm.js");
75
- await registerModuleHooks({
76
- appDir: appContext.appDirectory,
77
- distDir: appContext.distDirectory,
78
- alias: {}
79
- });
80
- }
81
- await (0, register_js_namespaceObject.setupTsRuntime)(appContext.appDirectory, appContext.distDirectory, combinedAlias);
73
+ await (0, register_js_namespaceObject.setupTsRuntime)(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
74
+ moduleType: appContext.moduleType
75
+ });
82
76
  const { apiOnly } = appContext;
83
77
  if (apiOnly) {
84
78
  await hooks.onBeforeBuild.call({
@@ -51,15 +51,10 @@ const dev = async (api, options, devServerOptions)=>{
51
51
  const appContext = api.getAppContext();
52
52
  const hooks = api.getHooks();
53
53
  const combinedAlias = [].concat(normalizedConfig?.resolve?.alias ?? []).concat(normalizedConfig?.source?.alias ?? []);
54
- if (appContext.moduleType && 'module' === appContext.moduleType) {
55
- const { registerModuleHooks } = await import("../esm/register-esm.js");
56
- await registerModuleHooks({
57
- appDir: appContext.appDirectory,
58
- distDir: appContext.distDirectory,
59
- alias: {}
60
- });
61
- }
62
- await (0, register_js_namespaceObject.setupTsRuntime)(appContext.appDirectory, appContext.distDirectory, combinedAlias);
54
+ await (0, register_js_namespaceObject.setupTsRuntime)(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
55
+ moduleType: appContext.moduleType,
56
+ preferTsNodeForServerRuntime: true
57
+ });
63
58
  const { appDirectory, port, apiOnly, metaName, serverRoutes } = appContext;
64
59
  const meta = (0, utils_namespaceObject.getMeta)(metaName);
65
60
  const serverConfigPath = external_node_path_default().resolve(appDirectory, utils_namespaceObject.SERVER_DIR, `${meta}.server`);
@@ -27,24 +27,16 @@ var __webpack_require__ = {};
27
27
  var __webpack_exports__ = {};
28
28
  __webpack_require__.r(__webpack_exports__);
29
29
  __webpack_require__.d(__webpack_exports__, {
30
- registerModuleHooks: ()=>registerModuleHooks
30
+ registerModuleHooks: ()=>registerModuleHooks,
31
+ registerPathsLoader: ()=>registerPathsLoader
31
32
  });
32
33
  const external_node_path_namespaceObject = require("node:path");
33
34
  const utils_namespaceObject = require("@modern-js/utils");
34
- const checkDepExist = async (dep)=>{
35
- try {
36
- await import(dep);
37
- return true;
38
- } catch {
39
- return false;
40
- }
41
- };
42
35
  const registerModuleHooks = async ({ appDir, distDir, alias })=>{
43
36
  const TS_CONFIG_FILENAME = "tsconfig.json";
44
37
  const tsconfigPath = external_node_path_namespaceObject.resolve(appDir, TS_CONFIG_FILENAME);
45
38
  const hasTsconfig = await utils_namespaceObject.fs.pathExists(tsconfigPath);
46
- const hasTsNode = await checkDepExist('ts-node');
47
- if (!hasTsconfig || !hasTsNode) return;
39
+ if (!hasTsconfig) return;
48
40
  const { register } = await import("node:module");
49
41
  process.env.TS_NODE_TRANSPILE_ONLY = true;
50
42
  process.env.TS_NODE_PROJECT = tsconfigPath;
@@ -60,9 +52,21 @@ const registerModuleHooks = async ({ appDir, distDir, alias })=>{
60
52
  }
61
53
  });
62
54
  };
55
+ const registerPathsLoader = async ({ appDir, baseUrl, paths })=>{
56
+ const { register } = await import("node:module");
57
+ register('./ts-paths-loader.mjs', __rslib_import_meta_url__, {
58
+ data: {
59
+ appDir,
60
+ baseUrl,
61
+ paths
62
+ }
63
+ });
64
+ };
63
65
  exports.registerModuleHooks = __webpack_exports__.registerModuleHooks;
66
+ exports.registerPathsLoader = __webpack_exports__.registerPathsLoader;
64
67
  for(var __rspack_i in __webpack_exports__)if (-1 === [
65
- "registerModuleHooks"
68
+ "registerModuleHooks",
69
+ "registerPathsLoader"
66
70
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
67
71
  Object.defineProperty(exports, '__esModule', {
68
72
  value: true
@@ -1,19 +1,10 @@
1
1
  import path from 'node:path';
2
2
  import { fs } from '@modern-js/utils';
3
- const checkDepExist = async (dep)=>{
4
- try {
5
- await import(dep);
6
- return true;
7
- } catch {
8
- return false;
9
- }
10
- };
11
3
  export const registerModuleHooks = async ({ appDir, distDir, alias })=>{
12
4
  const TS_CONFIG_FILENAME = "tsconfig.json";
13
5
  const tsconfigPath = path.resolve(appDir, TS_CONFIG_FILENAME);
14
6
  const hasTsconfig = await fs.pathExists(tsconfigPath);
15
- const hasTsNode = await checkDepExist('ts-node');
16
- if (!hasTsconfig || !hasTsNode) return;
7
+ if (!hasTsconfig) return;
17
8
  const { register } = await import('node:module');
18
9
  process.env.TS_NODE_TRANSPILE_ONLY = true;
19
10
  process.env.TS_NODE_PROJECT = tsconfigPath;
@@ -29,3 +20,13 @@ export const registerModuleHooks = async ({ appDir, distDir, alias })=>{
29
20
  }
30
21
  });
31
22
  };
23
+ export const registerPathsLoader = async ({ appDir, baseUrl, paths })=>{
24
+ const { register } = await import('node:module');
25
+ register('./ts-paths-loader.mjs', import.meta.url, {
26
+ data: {
27
+ appDir,
28
+ baseUrl,
29
+ paths
30
+ }
31
+ });
32
+ };
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ initialize: ()=>initialize,
28
+ resolve: ()=>resolve
29
+ });
30
+ const external_node_fs_namespaceObject = require("node:fs");
31
+ const external_node_path_namespaceObject = require("node:path");
32
+ const external_url_namespaceObject = require("url");
33
+ const tsconfig_paths_namespaceObject = require("@modern-js/utils/tsconfig-paths");
34
+ let matchPath;
35
+ let appDir;
36
+ const resolvePathWithExtensions = (matchedPath)=>{
37
+ if (external_node_path_namespaceObject.extname(matchedPath)) return matchedPath;
38
+ const fileCandidates = [
39
+ matchedPath,
40
+ `${matchedPath}.ts`,
41
+ `${matchedPath}.tsx`,
42
+ `${matchedPath}.mts`,
43
+ `${matchedPath}.cts`,
44
+ `${matchedPath}.js`,
45
+ `${matchedPath}.mjs`,
46
+ `${matchedPath}.cjs`
47
+ ];
48
+ for (const candidate of fileCandidates)if (external_node_fs_namespaceObject.existsSync(candidate) && external_node_fs_namespaceObject.statSync(candidate).isFile()) return candidate;
49
+ const indexCandidates = [
50
+ external_node_path_namespaceObject.join(matchedPath, 'index.ts'),
51
+ external_node_path_namespaceObject.join(matchedPath, 'index.tsx'),
52
+ external_node_path_namespaceObject.join(matchedPath, 'index.mts'),
53
+ external_node_path_namespaceObject.join(matchedPath, 'index.cts'),
54
+ external_node_path_namespaceObject.join(matchedPath, 'index.js'),
55
+ external_node_path_namespaceObject.join(matchedPath, 'index.mjs'),
56
+ external_node_path_namespaceObject.join(matchedPath, 'index.cjs')
57
+ ];
58
+ for (const candidate of indexCandidates)if (external_node_fs_namespaceObject.existsSync(candidate) && external_node_fs_namespaceObject.statSync(candidate).isFile()) return candidate;
59
+ return matchedPath;
60
+ };
61
+ async function initialize({ appDir: currentAppDir, baseUrl, paths }) {
62
+ appDir = external_node_path_namespaceObject.resolve(currentAppDir);
63
+ matchPath = (0, tsconfig_paths_namespaceObject.createMatchPath)(baseUrl || './', paths || {});
64
+ }
65
+ function resolve(specifier, context, defaultResolve) {
66
+ const parentPath = context.parentURL ? external_node_path_namespaceObject.dirname((0, external_url_namespaceObject.fileURLToPath)(context.parentURL)) : process.cwd();
67
+ const relativeFromApp = appDir ? external_node_path_namespaceObject.relative(appDir, parentPath) : '';
68
+ const isAppFile = appDir && (parentPath === appDir || relativeFromApp && !relativeFromApp.startsWith('..') && !external_node_path_namespaceObject.isAbsolute(relativeFromApp));
69
+ if ((specifier.startsWith('./') || specifier.startsWith('../')) && !external_node_path_namespaceObject.extname(specifier) && isAppFile) {
70
+ const resolvedPath = resolvePathWithExtensions(external_node_path_namespaceObject.resolve(parentPath, specifier));
71
+ if (resolvedPath && external_node_fs_namespaceObject.existsSync(resolvedPath)) return defaultResolve((0, external_url_namespaceObject.pathToFileURL)(resolvedPath).href, context, defaultResolve);
72
+ }
73
+ if (!matchPath) return defaultResolve(specifier, context, defaultResolve);
74
+ const match = matchPath(specifier, void 0, void 0, [
75
+ '.ts',
76
+ '.tsx',
77
+ '.mts',
78
+ '.cts',
79
+ '.js',
80
+ '.mjs',
81
+ '.cjs'
82
+ ]);
83
+ if (!match) return defaultResolve(specifier, context, defaultResolve);
84
+ const resolvedPath = resolvePathWithExtensions(match);
85
+ return defaultResolve((0, external_url_namespaceObject.pathToFileURL)(resolvedPath).href, context, defaultResolve);
86
+ }
87
+ exports.initialize = __webpack_exports__.initialize;
88
+ exports.resolve = __webpack_exports__.resolve;
89
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
90
+ "initialize",
91
+ "resolve"
92
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
93
+ Object.defineProperty(exports, '__esModule', {
94
+ value: true
95
+ });
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'url';
4
+ import { createMatchPath as oCreateMatchPath } from '@modern-js/utils/tsconfig-paths';
5
+ let matchPath;
6
+ let appDir;
7
+ const resolvePathWithExtensions = (matchedPath)=>{
8
+ if (path.extname(matchedPath)) return matchedPath;
9
+ const fileCandidates = [
10
+ matchedPath,
11
+ `${matchedPath}.ts`,
12
+ `${matchedPath}.tsx`,
13
+ `${matchedPath}.mts`,
14
+ `${matchedPath}.cts`,
15
+ `${matchedPath}.js`,
16
+ `${matchedPath}.mjs`,
17
+ `${matchedPath}.cjs`
18
+ ];
19
+ for (const candidate of fileCandidates)if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
20
+ const indexCandidates = [
21
+ path.join(matchedPath, 'index.ts'),
22
+ path.join(matchedPath, 'index.tsx'),
23
+ path.join(matchedPath, 'index.mts'),
24
+ path.join(matchedPath, 'index.cts'),
25
+ path.join(matchedPath, 'index.js'),
26
+ path.join(matchedPath, 'index.mjs'),
27
+ path.join(matchedPath, 'index.cjs')
28
+ ];
29
+ for (const candidate of indexCandidates)if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
30
+ return matchedPath;
31
+ };
32
+ export async function initialize({ appDir: currentAppDir, baseUrl, paths }) {
33
+ appDir = path.resolve(currentAppDir);
34
+ matchPath = oCreateMatchPath(baseUrl || './', paths || {});
35
+ }
36
+ export function resolve(specifier, context, defaultResolve) {
37
+ const parentPath = context.parentURL ? path.dirname(fileURLToPath(context.parentURL)) : process.cwd();
38
+ const relativeFromApp = appDir ? path.relative(appDir, parentPath) : '';
39
+ const isAppFile = appDir && (parentPath === appDir || relativeFromApp && !relativeFromApp.startsWith('..') && !path.isAbsolute(relativeFromApp));
40
+ if ((specifier.startsWith('./') || specifier.startsWith('../')) && !path.extname(specifier) && isAppFile) {
41
+ const resolvedPath = resolvePathWithExtensions(path.resolve(parentPath, specifier));
42
+ if (resolvedPath && fs.existsSync(resolvedPath)) return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
43
+ }
44
+ if (!matchPath) return defaultResolve(specifier, context, defaultResolve);
45
+ const match = matchPath(specifier, void 0, void 0, [
46
+ '.ts',
47
+ '.tsx',
48
+ '.mts',
49
+ '.cts',
50
+ '.js',
51
+ '.mjs',
52
+ '.cjs'
53
+ ]);
54
+ if (!match) return defaultResolve(specifier, context, defaultResolve);
55
+ const resolvedPath = resolvePathWithExtensions(match);
56
+ return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
57
+ }
@@ -68,7 +68,12 @@ const parseModule = async ({ source, filename })=>{
68
68
  if (utils_namespaceObject.JS_EXTENSIONS.some((ext)=>filename.endsWith(ext))) {
69
69
  const result = await (0, external_esbuild_namespaceObject.transform)(content, {
70
70
  loader: external_path_default().extname(filename).slice(1),
71
- format: 'esm'
71
+ format: 'esm',
72
+ tsconfigRaw: {
73
+ compilerOptions: {
74
+ experimentalDecorators: true
75
+ }
76
+ }
72
77
  });
73
78
  content = result.code;
74
79
  }
@@ -33,17 +33,28 @@ var __webpack_require__ = {};
33
33
  var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
- setupTsRuntime: ()=>setupTsRuntime
36
+ setupTsRuntime: ()=>setupTsRuntime,
37
+ resolveTsRuntimeRegisterMode: ()=>resolveTsRuntimeRegisterMode
37
38
  });
38
39
  const external_node_path_namespaceObject = require("node:path");
39
40
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
40
41
  const utils_namespaceObject = require("@modern-js/utils");
41
- const setupTsRuntime = async (appDir, distDir, alias)=>{
42
+ const resolveTsRuntimeRegisterMode = (hasTsNode)=>{
43
+ const hasNativeTypeScriptSupport = process.features?.typescript;
44
+ const nodeMajorVersion = Number(process.versions.node.split('.')[0]);
45
+ const supportsNativeTypeScript = void 0 === hasNativeTypeScriptSupport ? nodeMajorVersion >= 22 : false !== hasNativeTypeScriptSupport;
46
+ if (supportsNativeTypeScript) return 'node-loader';
47
+ if (hasTsNode) return 'ts-node';
48
+ return 'unsupported';
49
+ };
50
+ const setupTsRuntime = async (appDir, distDir, alias, options = {})=>{
42
51
  const TS_CONFIG_FILENAME = "tsconfig.json";
43
52
  const tsconfigPath = external_node_path_default().resolve(appDir, TS_CONFIG_FILENAME);
44
53
  const isTsProject = await utils_namespaceObject.fs.pathExists(tsconfigPath);
45
54
  const hasTsNode = (0, utils_namespaceObject.isDepExists)(appDir, 'ts-node');
46
- if (!isTsProject || !hasTsNode) return;
55
+ if (!isTsProject) return;
56
+ const preferredRegisterMode = resolveTsRuntimeRegisterMode(hasTsNode);
57
+ const registerMode = options.preferTsNodeForServerRuntime && hasTsNode ? 'ts-node' : preferredRegisterMode;
47
58
  const aliasConfig = (0, utils_namespaceObject.getAliasConfig)(alias, {
48
59
  appDirectory: appDir,
49
60
  tsconfigPath
@@ -68,28 +79,48 @@ const setupTsRuntime = async (appDir, distDir, alias)=>{
68
79
  [`${key}`]: tsPath
69
80
  };
70
81
  }, {});
71
- const tsConfig = (0, utils_namespaceObject.readTsConfigByFile)(tsconfigPath);
72
- const tsNode = await (0, utils_namespaceObject.loadFromProject)('ts-node', appDir);
73
- const tsNodeOptions = tsConfig['ts-node'];
74
- tsNode.register({
75
- project: tsconfigPath,
76
- scope: true,
77
- files: true,
78
- transpileOnly: true,
79
- ignore: [
80
- '(?:^|/)node_modules/',
81
- `(?:^|/)${external_node_path_default().relative(appDir, distDir)}/`
82
- ],
83
- ...tsNodeOptions
84
- });
82
+ if ('unsupported' === registerMode) return;
83
+ if ('ts-node' === registerMode) {
84
+ if ('module' === options.moduleType) {
85
+ const { registerModuleHooks } = await import("../esm/register-esm.js");
86
+ await registerModuleHooks({
87
+ appDir,
88
+ distDir,
89
+ alias: alias || {}
90
+ });
91
+ }
92
+ const tsConfig = (0, utils_namespaceObject.readTsConfigByFile)(tsconfigPath);
93
+ const tsNode = await (0, utils_namespaceObject.loadFromProject)('ts-node', appDir);
94
+ const tsNodeOptions = tsConfig['ts-node'];
95
+ tsNode.register({
96
+ project: tsconfigPath,
97
+ scope: true,
98
+ files: true,
99
+ transpileOnly: true,
100
+ ignore: [
101
+ '(?:^|/)node_modules/',
102
+ `(?:^|/)${external_node_path_default().relative(appDir, distDir)}/`
103
+ ],
104
+ ...tsNodeOptions
105
+ });
106
+ } else if ('node-loader' === registerMode) {
107
+ const { registerPathsLoader } = await import("../esm/register-esm.js");
108
+ await registerPathsLoader({
109
+ appDir,
110
+ baseUrl: absoluteBaseUrl || './',
111
+ paths: tsPaths
112
+ });
113
+ }
85
114
  const { register } = await import("@modern-js/utils/tsconfig-paths");
86
115
  register({
87
116
  baseUrl: absoluteBaseUrl || './',
88
117
  paths: tsPaths
89
118
  });
90
119
  };
120
+ exports.resolveTsRuntimeRegisterMode = __webpack_exports__.resolveTsRuntimeRegisterMode;
91
121
  exports.setupTsRuntime = __webpack_exports__.setupTsRuntime;
92
122
  for(var __rspack_i in __webpack_exports__)if (-1 === [
123
+ "resolveTsRuntimeRegisterMode",
93
124
  "setupTsRuntime"
94
125
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
95
126
  Object.defineProperty(exports, '__esModule', {
@@ -1,9 +1,9 @@
1
- import { resolve, sep } from "path";
2
1
  import { SERVICE_WORKER_ENVIRONMENT_NAME, isHtmlDisabled } from "@modern-js/builder";
3
2
  import { fs, isUseRsc, isUseSSRBundle } from "@modern-js/utils";
4
3
  import { mergeRsbuildConfig } from "@rsbuild/core";
5
4
  import { getServerCombinedModuleFile } from "../../../plugins/analyze/utils.mjs";
6
5
  import { HtmlAsyncChunkPlugin, RouterPlugin } from "../bundlerPlugins/index.mjs";
6
+ import * as __rspack_external_path from "path";
7
7
  const builderPluginAdapterSSR = (options)=>({
8
8
  name: 'builder-plugin-adapter-modern-ssr',
9
9
  setup (api) {
@@ -110,7 +110,7 @@ function applySSRDataLoader(chain, options) {
110
110
  const { normalizedConfig, appContext } = options;
111
111
  const { appDirectory } = appContext;
112
112
  const { entriesDir = './src' } = normalizedConfig.source;
113
- const absolutePath = resolve(appDirectory, entriesDir).split(sep).join('(\\\\|/)');
113
+ const absolutePath = __rspack_external_path.resolve(appDirectory, entriesDir).split(__rspack_external_path.sep).join('(\\\\|/)');
114
114
  const reg = new RegExp(`${absolutePath}.*\\.(loader|data|data.client)\\.[t|j]sx?$`);
115
115
  chain.module.rule('ssr-data-loader').test(reg).use('data-loader').loader(require.resolve('@modern-js/plugin-data-loader/loader')).end();
116
116
  }
@@ -32,15 +32,9 @@ const build = async (api, options)=>{
32
32
  const hooks = api.getHooks();
33
33
  const combinedAlias = [].concat(resolvedConfig?.resolve?.alias ?? []).concat(resolvedConfig?.source?.alias ?? []);
34
34
  await loadServerPlugins(api, appContext.appDirectory, appContext.metaName);
35
- if (appContext.moduleType && 'module' === appContext.moduleType) {
36
- const { registerModuleHooks } = await import("../esm/register-esm.mjs");
37
- await registerModuleHooks({
38
- appDir: appContext.appDirectory,
39
- distDir: appContext.distDirectory,
40
- alias: {}
41
- });
42
- }
43
- await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias);
35
+ await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
36
+ moduleType: appContext.moduleType
37
+ });
44
38
  const { apiOnly } = appContext;
45
39
  if (apiOnly) {
46
40
  await hooks.onBeforeBuild.call({
@@ -13,15 +13,10 @@ const dev = async (api, options, devServerOptions)=>{
13
13
  const appContext = api.getAppContext();
14
14
  const hooks = api.getHooks();
15
15
  const combinedAlias = [].concat(normalizedConfig?.resolve?.alias ?? []).concat(normalizedConfig?.source?.alias ?? []);
16
- if (appContext.moduleType && 'module' === appContext.moduleType) {
17
- const { registerModuleHooks } = await import("../esm/register-esm.mjs");
18
- await registerModuleHooks({
19
- appDir: appContext.appDirectory,
20
- distDir: appContext.distDirectory,
21
- alias: {}
22
- });
23
- }
24
- await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias);
16
+ await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
17
+ moduleType: appContext.moduleType,
18
+ preferTsNodeForServerRuntime: true
19
+ });
25
20
  const { appDirectory, port, apiOnly, metaName, serverRoutes } = appContext;
26
21
  const meta = getMeta(metaName);
27
22
  const serverConfigPath = node_path.resolve(appDirectory, SERVER_DIR, `${meta}.server`);
@@ -1,19 +1,10 @@
1
1
  import node_path from "node:path";
2
2
  import { fs } from "@modern-js/utils";
3
- const checkDepExist = async (dep)=>{
4
- try {
5
- await import(dep);
6
- return true;
7
- } catch {
8
- return false;
9
- }
10
- };
11
3
  const registerModuleHooks = async ({ appDir, distDir, alias })=>{
12
4
  const TS_CONFIG_FILENAME = "tsconfig.json";
13
5
  const tsconfigPath = node_path.resolve(appDir, TS_CONFIG_FILENAME);
14
6
  const hasTsconfig = await fs.pathExists(tsconfigPath);
15
- const hasTsNode = await checkDepExist('ts-node');
16
- if (!hasTsconfig || !hasTsNode) return;
7
+ if (!hasTsconfig) return;
17
8
  const { register } = await import("node:module");
18
9
  process.env.TS_NODE_TRANSPILE_ONLY = true;
19
10
  process.env.TS_NODE_PROJECT = tsconfigPath;
@@ -29,4 +20,14 @@ const registerModuleHooks = async ({ appDir, distDir, alias })=>{
29
20
  }
30
21
  });
31
22
  };
32
- export { registerModuleHooks };
23
+ const registerPathsLoader = async ({ appDir, baseUrl, paths })=>{
24
+ const { register } = await import("node:module");
25
+ register('./ts-paths-loader.mjs', import.meta.url, {
26
+ data: {
27
+ appDir,
28
+ baseUrl,
29
+ paths
30
+ }
31
+ });
32
+ };
33
+ export { registerModuleHooks, registerPathsLoader };
@@ -0,0 +1,58 @@
1
+ import node_fs from "node:fs";
2
+ import node_path from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "url";
4
+ import { createMatchPath } from "@modern-js/utils/tsconfig-paths";
5
+ let matchPath;
6
+ let appDir;
7
+ const resolvePathWithExtensions = (matchedPath)=>{
8
+ if (node_path.extname(matchedPath)) return matchedPath;
9
+ const fileCandidates = [
10
+ matchedPath,
11
+ `${matchedPath}.ts`,
12
+ `${matchedPath}.tsx`,
13
+ `${matchedPath}.mts`,
14
+ `${matchedPath}.cts`,
15
+ `${matchedPath}.js`,
16
+ `${matchedPath}.mjs`,
17
+ `${matchedPath}.cjs`
18
+ ];
19
+ for (const candidate of fileCandidates)if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
20
+ const indexCandidates = [
21
+ node_path.join(matchedPath, 'index.ts'),
22
+ node_path.join(matchedPath, 'index.tsx'),
23
+ node_path.join(matchedPath, 'index.mts'),
24
+ node_path.join(matchedPath, 'index.cts'),
25
+ node_path.join(matchedPath, 'index.js'),
26
+ node_path.join(matchedPath, 'index.mjs'),
27
+ node_path.join(matchedPath, 'index.cjs')
28
+ ];
29
+ for (const candidate of indexCandidates)if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
30
+ return matchedPath;
31
+ };
32
+ async function initialize({ appDir: currentAppDir, baseUrl, paths }) {
33
+ appDir = node_path.resolve(currentAppDir);
34
+ matchPath = createMatchPath(baseUrl || './', paths || {});
35
+ }
36
+ function resolve(specifier, context, defaultResolve) {
37
+ const parentPath = context.parentURL ? node_path.dirname(fileURLToPath(context.parentURL)) : process.cwd();
38
+ const relativeFromApp = appDir ? node_path.relative(appDir, parentPath) : '';
39
+ const isAppFile = appDir && (parentPath === appDir || relativeFromApp && !relativeFromApp.startsWith('..') && !node_path.isAbsolute(relativeFromApp));
40
+ if ((specifier.startsWith('./') || specifier.startsWith('../')) && !node_path.extname(specifier) && isAppFile) {
41
+ const resolvedPath = resolvePathWithExtensions(node_path.resolve(parentPath, specifier));
42
+ if (resolvedPath && node_fs.existsSync(resolvedPath)) return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
43
+ }
44
+ if (!matchPath) return defaultResolve(specifier, context, defaultResolve);
45
+ const match = matchPath(specifier, void 0, void 0, [
46
+ '.ts',
47
+ '.tsx',
48
+ '.mts',
49
+ '.cts',
50
+ '.js',
51
+ '.mjs',
52
+ '.cjs'
53
+ ]);
54
+ if (!match) return defaultResolve(specifier, context, defaultResolve);
55
+ const resolvedPath = resolvePathWithExtensions(match);
56
+ return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
57
+ }
58
+ export { initialize, resolve };
@@ -1,5 +1,3 @@
1
- export * from "./defineConfig.mjs";
2
- export * from "./types/index.mjs";
3
1
  import path from "path";
4
2
  import { castArray } from "@modern-js/builder";
5
3
  import { getLocaleLanguage } from "@modern-js/i18n-utils/language-detector";
@@ -17,6 +15,8 @@ import serverRuntime from "./plugins/serverRuntime.mjs";
17
15
  import { generateWatchFiles } from "./utils/generateWatchFiles.mjs";
18
16
  import { initAppContext } from "./utils/initAppContext.mjs";
19
17
  import { restart } from "./utils/restart.mjs";
18
+ export * from "./defineConfig.mjs";
19
+ export * from "./types/index.mjs";
20
20
  const appTools = ()=>({
21
21
  name: '@modern-js/app-tools',
22
22
  usePlugins: [
@@ -1,7 +1,7 @@
1
1
  import path from "path";
2
2
  import { findExists, fs } from "@modern-js/utils";
3
3
  import { HTML_PARTIALS_EXTENSIONS, HTML_PARTIALS_FOLDER } from "./constants.mjs";
4
- import { html } from "./templates.mjs";
4
+ import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
5
5
  const findPartials = (dir, entryName, position)=>{
6
6
  if (fs.existsSync(dir)) {
7
7
  const base = findExists(HTML_PARTIALS_EXTENSIONS.map((ext)=>path.resolve(dir, `${position}${ext}`)));
@@ -70,7 +70,7 @@ const getHtmlTemplate = async (entrypoints, hooks, { appContext, config })=>{
70
70
  partials: getModifyHtmlPartials(partials)
71
71
  });
72
72
  const templatePath = path.resolve(internalDirectory, entryName, 'index.html');
73
- fs.outputFileSync(templatePath, html(partials), 'utf8');
73
+ fs.outputFileSync(templatePath, __rspack_external__templates_mjs_4da4c6c8.html(partials), 'utf8');
74
74
  htmlTemplates[entryName] = templatePath.replace(/\\/g, '/');
75
75
  partialsByEntrypoint[entryName] = partials;
76
76
  const bottomTemplate = findPartials(htmlDir, name, "bottom");
@@ -1,5 +1,4 @@
1
1
  import { isPromise } from "node:util/types";
2
- import { extname, resolve } from "path";
3
2
  import { createDebugger, fs, getArgv, getMeta, isApiOnly, isDevCommand, minimist } from "@modern-js/utils";
4
3
  import { createBuilderGenerator } from "../../builder/index.mjs";
5
4
  import { initialNormalizedConfig } from "../../config/index.mjs";
@@ -8,6 +7,7 @@ import { getSelectedEntries } from "../../utils/getSelectedEntries.mjs";
8
7
  import { printInstructions } from "../../utils/printInstructions.mjs";
9
8
  import { generateRoutes } from "../../utils/routes.mjs";
10
9
  import { checkIsBuildCommands, checkIsServeCommand } from "./utils.mjs";
10
+ import * as __rspack_external_path from "path";
11
11
  const debug = createDebugger('plugin-analyze');
12
12
  const analyze = ()=>({
13
13
  name: '@modern-js/plugin-analyze',
@@ -74,7 +74,7 @@ const analyze = ()=>({
74
74
  };
75
75
  api.updateAppContext(appContext);
76
76
  nestedRouteEntries = entrypoints.map((point)=>point.nestedRoutesEntry).filter(Boolean);
77
- pagesDir = entrypoints.map((point)=>point.entry).filter((entry)=>entry && !extname(entry)).concat(nestedRouteEntries);
77
+ pagesDir = entrypoints.map((point)=>point.entry).filter((entry)=>entry && !__rspack_external_path.extname(entry)).concat(nestedRouteEntries);
78
78
  const meta = getMeta(api.getAppContext().metaName);
79
79
  const possibleNames = [
80
80
  `${meta}.routes.ts`,
@@ -88,7 +88,7 @@ const analyze = ()=>({
88
88
  const { absoluteEntryDir } = entrypoint;
89
89
  if (!absoluteEntryDir) return;
90
90
  for (const filename of possibleNames){
91
- const filePath = resolve(absoluteEntryDir, filename);
91
+ const filePath = __rspack_external_path.resolve(absoluteEntryDir, filename);
92
92
  if (await fs.pathExists(filePath)) {
93
93
  const stats = await fs.stat(filePath);
94
94
  if (stats.isFile()) routesConfigFiles.push(filePath);
@@ -1,8 +1,8 @@
1
1
  import fs from "fs";
2
2
  import { parse } from "@babel/parser";
3
3
  import traverse from "@babel/traverse";
4
- import { isArrowFunctionExpression, isFunctionDeclaration, isFunctionExpression } from "@babel/types";
5
- const isFunction = (node)=>isFunctionDeclaration(node) || isFunctionExpression(node) || isArrowFunctionExpression(node);
4
+ import * as __rspack_external__babel_types_69e65b52 from "@babel/types";
5
+ const isFunction = (node)=>__rspack_external__babel_types_69e65b52.isFunctionDeclaration(node) || __rspack_external__babel_types_69e65b52.isFunctionExpression(node) || __rspack_external__babel_types_69e65b52.isArrowFunctionExpression(node);
6
6
  const isDefaultExportFunction = (file)=>{
7
7
  if (!file || !fs.existsSync(file)) return false;
8
8
  const ast = parse(fs.readFileSync(file, 'utf8'), {
@@ -23,7 +23,12 @@ const parseModule = async ({ source, filename })=>{
23
23
  if (JS_EXTENSIONS.some((ext)=>filename.endsWith(ext))) {
24
24
  const result = await transform(content, {
25
25
  loader: path.extname(filename).slice(1),
26
- format: 'esm'
26
+ format: 'esm',
27
+ tsconfigRaw: {
28
+ compilerOptions: {
29
+ experimentalDecorators: true
30
+ }
31
+ }
27
32
  });
28
33
  content = result.code;
29
34
  }
@@ -1,8 +1,8 @@
1
- import { join } from "path";
2
1
  import { OUTPUT_CONFIG_FILE, ensureAbsolutePath, fs } from "@modern-js/utils";
3
2
  import { stringify } from "flatted";
3
+ import * as __rspack_external_path from "path";
4
4
  const emitResolvedConfig = async (appDirectory, resolvedConfig)=>{
5
- const outputPath = ensureAbsolutePath(appDirectory, join(resolvedConfig.output.distPath?.root || './dist', OUTPUT_CONFIG_FILE));
5
+ const outputPath = ensureAbsolutePath(appDirectory, __rspack_external_path.join(resolvedConfig.output.distPath?.root || './dist', OUTPUT_CONFIG_FILE));
6
6
  const output = stringify(resolvedConfig);
7
7
  await fs.writeFile(outputPath, output, {
8
8
  encoding: 'utf-8'
@@ -1,11 +1,21 @@
1
1
  import node_path from "node:path";
2
2
  import { fs, getAliasConfig, isDepExists, loadFromProject, readTsConfigByFile } from "@modern-js/utils";
3
- const setupTsRuntime = async (appDir, distDir, alias)=>{
3
+ const resolveTsRuntimeRegisterMode = (hasTsNode)=>{
4
+ const hasNativeTypeScriptSupport = process.features?.typescript;
5
+ const nodeMajorVersion = Number(process.versions.node.split('.')[0]);
6
+ const supportsNativeTypeScript = void 0 === hasNativeTypeScriptSupport ? nodeMajorVersion >= 22 : false !== hasNativeTypeScriptSupport;
7
+ if (supportsNativeTypeScript) return 'node-loader';
8
+ if (hasTsNode) return 'ts-node';
9
+ return 'unsupported';
10
+ };
11
+ const setupTsRuntime = async (appDir, distDir, alias, options = {})=>{
4
12
  const TS_CONFIG_FILENAME = "tsconfig.json";
5
13
  const tsconfigPath = node_path.resolve(appDir, TS_CONFIG_FILENAME);
6
14
  const isTsProject = await fs.pathExists(tsconfigPath);
7
15
  const hasTsNode = isDepExists(appDir, 'ts-node');
8
- if (!isTsProject || !hasTsNode) return;
16
+ if (!isTsProject) return;
17
+ const preferredRegisterMode = resolveTsRuntimeRegisterMode(hasTsNode);
18
+ const registerMode = options.preferTsNodeForServerRuntime && hasTsNode ? 'ts-node' : preferredRegisterMode;
9
19
  const aliasConfig = getAliasConfig(alias, {
10
20
  appDirectory: appDir,
11
21
  tsconfigPath
@@ -30,24 +40,42 @@ const setupTsRuntime = async (appDir, distDir, alias)=>{
30
40
  [`${key}`]: tsPath
31
41
  };
32
42
  }, {});
33
- const tsConfig = readTsConfigByFile(tsconfigPath);
34
- const tsNode = await loadFromProject('ts-node', appDir);
35
- const tsNodeOptions = tsConfig['ts-node'];
36
- tsNode.register({
37
- project: tsconfigPath,
38
- scope: true,
39
- files: true,
40
- transpileOnly: true,
41
- ignore: [
42
- '(?:^|/)node_modules/',
43
- `(?:^|/)${node_path.relative(appDir, distDir)}/`
44
- ],
45
- ...tsNodeOptions
46
- });
43
+ if ('unsupported' === registerMode) return;
44
+ if ('ts-node' === registerMode) {
45
+ if ('module' === options.moduleType) {
46
+ const { registerModuleHooks } = await import("../esm/register-esm.mjs");
47
+ await registerModuleHooks({
48
+ appDir,
49
+ distDir,
50
+ alias: alias || {}
51
+ });
52
+ }
53
+ const tsConfig = readTsConfigByFile(tsconfigPath);
54
+ const tsNode = await loadFromProject('ts-node', appDir);
55
+ const tsNodeOptions = tsConfig['ts-node'];
56
+ tsNode.register({
57
+ project: tsconfigPath,
58
+ scope: true,
59
+ files: true,
60
+ transpileOnly: true,
61
+ ignore: [
62
+ '(?:^|/)node_modules/',
63
+ `(?:^|/)${node_path.relative(appDir, distDir)}/`
64
+ ],
65
+ ...tsNodeOptions
66
+ });
67
+ } else if ('node-loader' === registerMode) {
68
+ const { registerPathsLoader } = await import("../esm/register-esm.mjs");
69
+ await registerPathsLoader({
70
+ appDir,
71
+ baseUrl: absoluteBaseUrl || './',
72
+ paths: tsPaths
73
+ });
74
+ }
47
75
  const { register } = await import("@modern-js/utils/tsconfig-paths");
48
76
  register({
49
77
  baseUrl: absoluteBaseUrl || './',
50
78
  paths: tsPaths
51
79
  });
52
80
  };
53
- export { setupTsRuntime };
81
+ export { resolveTsRuntimeRegisterMode, setupTsRuntime };
@@ -1,8 +1,8 @@
1
1
  import "node:module";
2
- import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
3
- import { dirname as __rspack_dirname } from "node:path";
4
2
  import node_path from "node:path";
5
3
  import { SERVICE_WORKER_ENVIRONMENT_NAME } from "@modern-js/builder";
4
+ import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
5
+ import { dirname as __rspack_dirname } from "node:path";
6
6
  var adapterBasic_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
7
7
  const builderPluginAdapterBasic = (options)=>({
8
8
  name: 'builder-plugin-adapter-modern-basic',
@@ -1,11 +1,11 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
- import { resolve, sep } from "path";
4
3
  import { SERVICE_WORKER_ENVIRONMENT_NAME, isHtmlDisabled } from "@modern-js/builder";
5
4
  import { fs, isUseRsc, isUseSSRBundle } from "@modern-js/utils";
6
5
  import { mergeRsbuildConfig } from "@rsbuild/core";
7
6
  import { getServerCombinedModuleFile } from "../../../plugins/analyze/utils.mjs";
8
7
  import { HtmlAsyncChunkPlugin, RouterPlugin } from "../bundlerPlugins/index.mjs";
8
+ import * as __rspack_external_path from "path";
9
9
  const builderPluginAdapterSSR = (options)=>({
10
10
  name: 'builder-plugin-adapter-modern-ssr',
11
11
  setup (api) {
@@ -112,7 +112,7 @@ function applySSRDataLoader(chain, options) {
112
112
  const { normalizedConfig, appContext } = options;
113
113
  const { appDirectory } = appContext;
114
114
  const { entriesDir = './src' } = normalizedConfig.source;
115
- const absolutePath = resolve(appDirectory, entriesDir).split(sep).join('(\\\\|/)');
115
+ const absolutePath = __rspack_external_path.resolve(appDirectory, entriesDir).split(__rspack_external_path.sep).join('(\\\\|/)');
116
116
  const reg = new RegExp(`${absolutePath}.*\\.(loader|data|data.client)\\.[t|j]sx?$`);
117
117
  chain.module.rule('ssr-data-loader').test(reg).use('data-loader').loader(require.resolve('@modern-js/plugin-data-loader/loader')).end();
118
118
  }
@@ -33,15 +33,9 @@ const build = async (api, options)=>{
33
33
  const hooks = api.getHooks();
34
34
  const combinedAlias = [].concat(resolvedConfig?.resolve?.alias ?? []).concat(resolvedConfig?.source?.alias ?? []);
35
35
  await loadServerPlugins(api, appContext.appDirectory, appContext.metaName);
36
- if (appContext.moduleType && 'module' === appContext.moduleType) {
37
- const { registerModuleHooks } = await import("../esm/register-esm.mjs");
38
- await registerModuleHooks({
39
- appDir: appContext.appDirectory,
40
- distDir: appContext.distDirectory,
41
- alias: {}
42
- });
43
- }
44
- await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias);
36
+ await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
37
+ moduleType: appContext.moduleType
38
+ });
45
39
  const { apiOnly } = appContext;
46
40
  if (apiOnly) {
47
41
  await hooks.onBeforeBuild.call({
@@ -14,15 +14,10 @@ const dev = async (api, options, devServerOptions)=>{
14
14
  const appContext = api.getAppContext();
15
15
  const hooks = api.getHooks();
16
16
  const combinedAlias = [].concat(normalizedConfig?.resolve?.alias ?? []).concat(normalizedConfig?.source?.alias ?? []);
17
- if (appContext.moduleType && 'module' === appContext.moduleType) {
18
- const { registerModuleHooks } = await import("../esm/register-esm.mjs");
19
- await registerModuleHooks({
20
- appDir: appContext.appDirectory,
21
- distDir: appContext.distDirectory,
22
- alias: {}
23
- });
24
- }
25
- await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias);
17
+ await setupTsRuntime(appContext.appDirectory, appContext.distDirectory, combinedAlias, {
18
+ moduleType: appContext.moduleType,
19
+ preferTsNodeForServerRuntime: true
20
+ });
26
21
  const { appDirectory, port, apiOnly, metaName, serverRoutes } = appContext;
27
22
  const meta = getMeta(metaName);
28
23
  const serverConfigPath = node_path.resolve(appDirectory, SERVER_DIR, `${meta}.server`);
@@ -1,20 +1,11 @@
1
1
  import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { fs } from "@modern-js/utils";
4
- const checkDepExist = async (dep)=>{
5
- try {
6
- await import(dep);
7
- return true;
8
- } catch {
9
- return false;
10
- }
11
- };
12
4
  const registerModuleHooks = async ({ appDir, distDir, alias })=>{
13
5
  const TS_CONFIG_FILENAME = "tsconfig.json";
14
6
  const tsconfigPath = node_path.resolve(appDir, TS_CONFIG_FILENAME);
15
7
  const hasTsconfig = await fs.pathExists(tsconfigPath);
16
- const hasTsNode = await checkDepExist('ts-node');
17
- if (!hasTsconfig || !hasTsNode) return;
8
+ if (!hasTsconfig) return;
18
9
  const { register } = await import("node:module");
19
10
  process.env.TS_NODE_TRANSPILE_ONLY = true;
20
11
  process.env.TS_NODE_PROJECT = tsconfigPath;
@@ -30,4 +21,14 @@ const registerModuleHooks = async ({ appDir, distDir, alias })=>{
30
21
  }
31
22
  });
32
23
  };
33
- export { registerModuleHooks };
24
+ const registerPathsLoader = async ({ appDir, baseUrl, paths })=>{
25
+ const { register } = await import("node:module");
26
+ register('./ts-paths-loader.mjs', import.meta.url, {
27
+ data: {
28
+ appDir,
29
+ baseUrl,
30
+ paths
31
+ }
32
+ });
33
+ };
34
+ export { registerModuleHooks, registerPathsLoader };
@@ -0,0 +1,59 @@
1
+ import "node:module";
2
+ import node_fs from "node:fs";
3
+ import node_path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "url";
5
+ import { createMatchPath } from "@modern-js/utils/tsconfig-paths";
6
+ let matchPath;
7
+ let appDir;
8
+ const resolvePathWithExtensions = (matchedPath)=>{
9
+ if (node_path.extname(matchedPath)) return matchedPath;
10
+ const fileCandidates = [
11
+ matchedPath,
12
+ `${matchedPath}.ts`,
13
+ `${matchedPath}.tsx`,
14
+ `${matchedPath}.mts`,
15
+ `${matchedPath}.cts`,
16
+ `${matchedPath}.js`,
17
+ `${matchedPath}.mjs`,
18
+ `${matchedPath}.cjs`
19
+ ];
20
+ for (const candidate of fileCandidates)if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
21
+ const indexCandidates = [
22
+ node_path.join(matchedPath, 'index.ts'),
23
+ node_path.join(matchedPath, 'index.tsx'),
24
+ node_path.join(matchedPath, 'index.mts'),
25
+ node_path.join(matchedPath, 'index.cts'),
26
+ node_path.join(matchedPath, 'index.js'),
27
+ node_path.join(matchedPath, 'index.mjs'),
28
+ node_path.join(matchedPath, 'index.cjs')
29
+ ];
30
+ for (const candidate of indexCandidates)if (node_fs.existsSync(candidate) && node_fs.statSync(candidate).isFile()) return candidate;
31
+ return matchedPath;
32
+ };
33
+ async function initialize({ appDir: currentAppDir, baseUrl, paths }) {
34
+ appDir = node_path.resolve(currentAppDir);
35
+ matchPath = createMatchPath(baseUrl || './', paths || {});
36
+ }
37
+ function resolve(specifier, context, defaultResolve) {
38
+ const parentPath = context.parentURL ? node_path.dirname(fileURLToPath(context.parentURL)) : process.cwd();
39
+ const relativeFromApp = appDir ? node_path.relative(appDir, parentPath) : '';
40
+ const isAppFile = appDir && (parentPath === appDir || relativeFromApp && !relativeFromApp.startsWith('..') && !node_path.isAbsolute(relativeFromApp));
41
+ if ((specifier.startsWith('./') || specifier.startsWith('../')) && !node_path.extname(specifier) && isAppFile) {
42
+ const resolvedPath = resolvePathWithExtensions(node_path.resolve(parentPath, specifier));
43
+ if (resolvedPath && node_fs.existsSync(resolvedPath)) return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
44
+ }
45
+ if (!matchPath) return defaultResolve(specifier, context, defaultResolve);
46
+ const match = matchPath(specifier, void 0, void 0, [
47
+ '.ts',
48
+ '.tsx',
49
+ '.mts',
50
+ '.cts',
51
+ '.js',
52
+ '.mjs',
53
+ '.cjs'
54
+ ]);
55
+ if (!match) return defaultResolve(specifier, context, defaultResolve);
56
+ const resolvedPath = resolvePathWithExtensions(match);
57
+ return defaultResolve(pathToFileURL(resolvedPath).href, context, defaultResolve);
58
+ }
59
+ export { initialize, resolve };
@@ -1,7 +1,5 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
- export * from "./defineConfig.mjs";
4
- export * from "./types/index.mjs";
5
3
  import path from "path";
6
4
  import { castArray } from "@modern-js/builder";
7
5
  import { getLocaleLanguage } from "@modern-js/i18n-utils/language-detector";
@@ -19,6 +17,8 @@ import serverRuntime from "./plugins/serverRuntime.mjs";
19
17
  import { generateWatchFiles } from "./utils/generateWatchFiles.mjs";
20
18
  import { initAppContext } from "./utils/initAppContext.mjs";
21
19
  import { restart } from "./utils/restart.mjs";
20
+ export * from "./defineConfig.mjs";
21
+ export * from "./types/index.mjs";
22
22
  const appTools = ()=>({
23
23
  name: '@modern-js/app-tools',
24
24
  usePlugins: [
@@ -2,7 +2,7 @@ import "node:module";
2
2
  import path from "path";
3
3
  import { findExists, fs } from "@modern-js/utils";
4
4
  import { HTML_PARTIALS_EXTENSIONS, HTML_PARTIALS_FOLDER } from "./constants.mjs";
5
- import { html } from "./templates.mjs";
5
+ import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
6
6
  const findPartials = (dir, entryName, position)=>{
7
7
  if (fs.existsSync(dir)) {
8
8
  const base = findExists(HTML_PARTIALS_EXTENSIONS.map((ext)=>path.resolve(dir, `${position}${ext}`)));
@@ -71,7 +71,7 @@ const getHtmlTemplate = async (entrypoints, hooks, { appContext, config })=>{
71
71
  partials: getModifyHtmlPartials(partials)
72
72
  });
73
73
  const templatePath = path.resolve(internalDirectory, entryName, 'index.html');
74
- fs.outputFileSync(templatePath, html(partials), 'utf8');
74
+ fs.outputFileSync(templatePath, __rspack_external__templates_mjs_4da4c6c8.html(partials), 'utf8');
75
75
  htmlTemplates[entryName] = templatePath.replace(/\\/g, '/');
76
76
  partialsByEntrypoint[entryName] = partials;
77
77
  const bottomTemplate = findPartials(htmlDir, name, "bottom");
@@ -1,6 +1,5 @@
1
1
  import "node:module";
2
2
  import { isPromise } from "node:util/types";
3
- import { extname, resolve } from "path";
4
3
  import { createDebugger, fs, getArgv, getMeta, isApiOnly, isDevCommand, minimist } from "@modern-js/utils";
5
4
  import { createBuilderGenerator } from "../../builder/index.mjs";
6
5
  import { initialNormalizedConfig } from "../../config/index.mjs";
@@ -9,6 +8,7 @@ import { getSelectedEntries } from "../../utils/getSelectedEntries.mjs";
9
8
  import { printInstructions } from "../../utils/printInstructions.mjs";
10
9
  import { generateRoutes } from "../../utils/routes.mjs";
11
10
  import { checkIsBuildCommands, checkIsServeCommand } from "./utils.mjs";
11
+ import * as __rspack_external_path from "path";
12
12
  const debug = createDebugger('plugin-analyze');
13
13
  const analyze = ()=>({
14
14
  name: '@modern-js/plugin-analyze',
@@ -75,7 +75,7 @@ const analyze = ()=>({
75
75
  };
76
76
  api.updateAppContext(appContext);
77
77
  nestedRouteEntries = entrypoints.map((point)=>point.nestedRoutesEntry).filter(Boolean);
78
- pagesDir = entrypoints.map((point)=>point.entry).filter((entry)=>entry && !extname(entry)).concat(nestedRouteEntries);
78
+ pagesDir = entrypoints.map((point)=>point.entry).filter((entry)=>entry && !__rspack_external_path.extname(entry)).concat(nestedRouteEntries);
79
79
  const meta = getMeta(api.getAppContext().metaName);
80
80
  const possibleNames = [
81
81
  `${meta}.routes.ts`,
@@ -89,7 +89,7 @@ const analyze = ()=>({
89
89
  const { absoluteEntryDir } = entrypoint;
90
90
  if (!absoluteEntryDir) return;
91
91
  for (const filename of possibleNames){
92
- const filePath = resolve(absoluteEntryDir, filename);
92
+ const filePath = __rspack_external_path.resolve(absoluteEntryDir, filename);
93
93
  if (await fs.pathExists(filePath)) {
94
94
  const stats = await fs.stat(filePath);
95
95
  if (stats.isFile()) routesConfigFiles.push(filePath);
@@ -2,8 +2,8 @@ import "node:module";
2
2
  import fs from "fs";
3
3
  import { parse } from "@babel/parser";
4
4
  import traverse from "@babel/traverse";
5
- import { isArrowFunctionExpression, isFunctionDeclaration, isFunctionExpression } from "@babel/types";
6
- const isFunction = (node)=>isFunctionDeclaration(node) || isFunctionExpression(node) || isArrowFunctionExpression(node);
5
+ import * as __rspack_external__babel_types_69e65b52 from "@babel/types";
6
+ const isFunction = (node)=>__rspack_external__babel_types_69e65b52.isFunctionDeclaration(node) || __rspack_external__babel_types_69e65b52.isFunctionExpression(node) || __rspack_external__babel_types_69e65b52.isArrowFunctionExpression(node);
7
7
  const isDefaultExportFunction = (file)=>{
8
8
  if (!file || !fs.existsSync(file)) return false;
9
9
  const ast = parse(fs.readFileSync(file, 'utf8'), {
@@ -24,7 +24,12 @@ const parseModule = async ({ source, filename })=>{
24
24
  if (JS_EXTENSIONS.some((ext)=>filename.endsWith(ext))) {
25
25
  const result = await transform(content, {
26
26
  loader: path.extname(filename).slice(1),
27
- format: 'esm'
27
+ format: 'esm',
28
+ tsconfigRaw: {
29
+ compilerOptions: {
30
+ experimentalDecorators: true
31
+ }
32
+ }
28
33
  });
29
34
  content = result.code;
30
35
  }
@@ -1,9 +1,9 @@
1
1
  import "node:module";
2
- import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
3
- import { dirname as __rspack_dirname } from "node:path";
4
2
  import { pathToFileURL } from "node:url";
5
3
  import path from "path";
6
4
  import { ROUTE_SPEC_FILE, SERVER_DIR, fs, getMeta } from "@modern-js/utils";
5
+ import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
6
+ import { dirname as __rspack_dirname } from "node:path";
7
7
  var utils_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
8
8
  const normalizePath = (filePath)=>filePath.replace(/\\/g, '/');
9
9
  const getProjectUsage = (appDirectory, distDirectory, metaName)=>{
@@ -1,9 +1,9 @@
1
1
  import "node:module";
2
- import { join } from "path";
3
2
  import { OUTPUT_CONFIG_FILE, ensureAbsolutePath, fs } from "@modern-js/utils";
4
3
  import { stringify } from "flatted";
4
+ import * as __rspack_external_path from "path";
5
5
  const emitResolvedConfig = async (appDirectory, resolvedConfig)=>{
6
- const outputPath = ensureAbsolutePath(appDirectory, join(resolvedConfig.output.distPath?.root || './dist', OUTPUT_CONFIG_FILE));
6
+ const outputPath = ensureAbsolutePath(appDirectory, __rspack_external_path.join(resolvedConfig.output.distPath?.root || './dist', OUTPUT_CONFIG_FILE));
7
7
  const output = stringify(resolvedConfig);
8
8
  await fs.writeFile(outputPath, output, {
9
9
  encoding: 'utf-8'
@@ -2,12 +2,22 @@ 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
4
  import { fs, getAliasConfig, isDepExists, loadFromProject, readTsConfigByFile } from "@modern-js/utils";
5
- const setupTsRuntime = async (appDir, distDir, alias)=>{
5
+ const resolveTsRuntimeRegisterMode = (hasTsNode)=>{
6
+ const hasNativeTypeScriptSupport = process.features?.typescript;
7
+ const nodeMajorVersion = Number(process.versions.node.split('.')[0]);
8
+ const supportsNativeTypeScript = void 0 === hasNativeTypeScriptSupport ? nodeMajorVersion >= 22 : false !== hasNativeTypeScriptSupport;
9
+ if (supportsNativeTypeScript) return 'node-loader';
10
+ if (hasTsNode) return 'ts-node';
11
+ return 'unsupported';
12
+ };
13
+ const setupTsRuntime = async (appDir, distDir, alias, options = {})=>{
6
14
  const TS_CONFIG_FILENAME = "tsconfig.json";
7
15
  const tsconfigPath = node_path.resolve(appDir, TS_CONFIG_FILENAME);
8
16
  const isTsProject = await fs.pathExists(tsconfigPath);
9
17
  const hasTsNode = isDepExists(appDir, 'ts-node');
10
- if (!isTsProject || !hasTsNode) return;
18
+ if (!isTsProject) return;
19
+ const preferredRegisterMode = resolveTsRuntimeRegisterMode(hasTsNode);
20
+ const registerMode = options.preferTsNodeForServerRuntime && hasTsNode ? 'ts-node' : preferredRegisterMode;
11
21
  const aliasConfig = getAliasConfig(alias, {
12
22
  appDirectory: appDir,
13
23
  tsconfigPath
@@ -32,24 +42,42 @@ const setupTsRuntime = async (appDir, distDir, alias)=>{
32
42
  [`${key}`]: tsPath
33
43
  };
34
44
  }, {});
35
- const tsConfig = readTsConfigByFile(tsconfigPath);
36
- const tsNode = await loadFromProject('ts-node', appDir);
37
- const tsNodeOptions = tsConfig['ts-node'];
38
- tsNode.register({
39
- project: tsconfigPath,
40
- scope: true,
41
- files: true,
42
- transpileOnly: true,
43
- ignore: [
44
- '(?:^|/)node_modules/',
45
- `(?:^|/)${node_path.relative(appDir, distDir)}/`
46
- ],
47
- ...tsNodeOptions
48
- });
45
+ if ('unsupported' === registerMode) return;
46
+ if ('ts-node' === registerMode) {
47
+ if ('module' === options.moduleType) {
48
+ const { registerModuleHooks } = await import("../esm/register-esm.mjs");
49
+ await registerModuleHooks({
50
+ appDir,
51
+ distDir,
52
+ alias: alias || {}
53
+ });
54
+ }
55
+ const tsConfig = readTsConfigByFile(tsconfigPath);
56
+ const tsNode = await loadFromProject('ts-node', appDir);
57
+ const tsNodeOptions = tsConfig['ts-node'];
58
+ tsNode.register({
59
+ project: tsconfigPath,
60
+ scope: true,
61
+ files: true,
62
+ transpileOnly: true,
63
+ ignore: [
64
+ '(?:^|/)node_modules/',
65
+ `(?:^|/)${node_path.relative(appDir, distDir)}/`
66
+ ],
67
+ ...tsNodeOptions
68
+ });
69
+ } else if ('node-loader' === registerMode) {
70
+ const { registerPathsLoader } = await import("../esm/register-esm.mjs");
71
+ await registerPathsLoader({
72
+ appDir,
73
+ baseUrl: absoluteBaseUrl || './',
74
+ paths: tsPaths
75
+ });
76
+ }
49
77
  const { register } = await import("@modern-js/utils/tsconfig-paths");
50
78
  register({
51
79
  baseUrl: absoluteBaseUrl || './',
52
80
  paths: tsPaths
53
81
  });
54
82
  };
55
- export { setupTsRuntime };
83
+ export { resolveTsRuntimeRegisterMode, setupTsRuntime };
@@ -3,3 +3,8 @@ export function registerModuleHooks({ appDir, distDir, alias }: {
3
3
  distDir: any;
4
4
  alias: any;
5
5
  }): Promise<void>;
6
+ export function registerPathsLoader({ appDir, baseUrl, paths }: {
7
+ appDir: any;
8
+ baseUrl: any;
9
+ paths: any;
10
+ }): Promise<void>;
@@ -0,0 +1,6 @@
1
+ export function initialize({ appDir: currentAppDir, baseUrl, paths }: {
2
+ appDir: any;
3
+ baseUrl: any;
4
+ paths: any;
5
+ }): Promise<void>;
6
+ export function resolve(specifier: any, context: any, defaultResolve: any): any;
@@ -1,7 +1,14 @@
1
1
  import { type Alias } from '@modern-js/utils';
2
2
  import type { ConfigChain } from '@rsbuild/core';
3
+ type TsRuntimeRegisterMode = 'ts-node' | 'node-loader' | 'unsupported';
4
+ interface TsRuntimeSetupOptions {
5
+ moduleType?: string;
6
+ preferTsNodeForServerRuntime?: boolean;
7
+ }
8
+ export declare const resolveTsRuntimeRegisterMode: (hasTsNode: boolean) => TsRuntimeRegisterMode;
3
9
  /**
4
10
  * Setup TypeScript runtime support.
5
11
  * Register ts-node for compilation and tsconfig-paths for path alias resolution.
6
12
  */
7
- export declare const setupTsRuntime: (appDir: string, distDir: string, alias?: ConfigChain<Alias>) => Promise<void>;
13
+ export declare const setupTsRuntime: (appDir: string, distDir: string, alias?: ConfigChain<Alias>, options?: TsRuntimeSetupOptions) => Promise<void>;
14
+ export {};
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "3.1.1",
18
+ "version": "3.1.3",
19
19
  "types": "./dist/types/index.d.ts",
20
20
  "main": "./dist/cjs/index.js",
21
21
  "exports": {
@@ -80,33 +80,33 @@
80
80
  "modern-app": "./bin/modern.js"
81
81
  },
82
82
  "dependencies": {
83
- "@babel/parser": "^7.29.0",
83
+ "@babel/parser": "^7.29.2",
84
84
  "@babel/traverse": "^7.29.0",
85
85
  "@babel/types": "^7.29.0",
86
- "@rsbuild/core": "2.0.0-beta.4",
86
+ "@rsbuild/core": "2.0.0-rc.0",
87
87
  "@swc/helpers": "^0.5.17",
88
88
  "es-module-lexer": "^1.7.0",
89
89
  "esbuild": "0.25.5",
90
90
  "esbuild-register": "^3.6.0",
91
91
  "import-meta-resolve": "^4.2.0",
92
- "flatted": "^3.4.0",
92
+ "flatted": "^3.4.2",
93
93
  "mlly": "^1.8.0",
94
94
  "ndepe": "^0.1.13",
95
95
  "pkg-types": "^1.3.1",
96
96
  "std-env": "^3.10.0",
97
- "@modern-js/builder": "3.1.1",
98
- "@modern-js/i18n-utils": "3.1.1",
99
- "@modern-js/plugin": "3.1.1",
100
- "@modern-js/plugin-data-loader": "3.1.1",
101
- "@modern-js/prod-server": "3.1.1",
102
- "@modern-js/server": "3.1.1",
103
- "@modern-js/server-utils": "3.1.1",
104
- "@modern-js/server-core": "3.1.1",
105
- "@modern-js/utils": "3.1.1",
106
- "@modern-js/types": "3.1.1"
97
+ "@modern-js/builder": "3.1.3",
98
+ "@modern-js/i18n-utils": "3.1.3",
99
+ "@modern-js/plugin-data-loader": "3.1.3",
100
+ "@modern-js/plugin": "3.1.3",
101
+ "@modern-js/prod-server": "3.1.3",
102
+ "@modern-js/server": "3.1.3",
103
+ "@modern-js/server-core": "3.1.3",
104
+ "@modern-js/server-utils": "3.1.3",
105
+ "@modern-js/types": "3.1.3",
106
+ "@modern-js/utils": "3.1.3"
107
107
  },
108
108
  "devDependencies": {
109
- "@rslib/core": "0.20.0",
109
+ "@rslib/core": "0.21.0",
110
110
  "@types/babel__traverse": "7.28.0",
111
111
  "@types/node": "^20",
112
112
  "ts-node": "^10.9.2",