@bleedingdev/modern-js-app-tools 3.2.0-ultramodern.9 → 3.2.0-ultramodern.90

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 (43) hide show
  1. package/dist/cjs/baseline.js +43 -1
  2. package/dist/cjs/builder/generator/getBuilderEnvironments.js +175 -8
  3. package/dist/cjs/builder/shared/builderPlugins/adapterBasic.js +41 -5
  4. package/dist/cjs/builder/shared/builderPlugins/adapterSSR.js +3 -1
  5. package/dist/cjs/plugins/deploy/index.js +17 -6
  6. package/dist/cjs/plugins/deploy/platforms/cloudflare.js +221 -0
  7. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-entry.mjs +438 -0
  8. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-fs-promises.mjs +7 -0
  9. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-loadable-server.mjs +185 -0
  10. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-path.mjs +59 -0
  11. package/dist/cjs/rsbuild.js +3 -0
  12. package/dist/esm/baseline.mjs +33 -1
  13. package/dist/esm/builder/generator/getBuilderEnvironments.mjs +164 -8
  14. package/dist/esm/builder/shared/builderPlugins/adapterBasic.mjs +41 -5
  15. package/dist/esm/builder/shared/builderPlugins/adapterSSR.mjs +3 -1
  16. package/dist/esm/plugins/deploy/index.mjs +10 -4
  17. package/dist/esm/plugins/deploy/platforms/cloudflare.mjs +177 -0
  18. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-entry.mjs +438 -0
  19. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-fs-promises.mjs +7 -0
  20. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-loadable-server.mjs +185 -0
  21. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-path.mjs +59 -0
  22. package/dist/esm/rsbuild.mjs +5 -2
  23. package/dist/esm-node/baseline.mjs +33 -1
  24. package/dist/esm-node/builder/generator/getBuilderEnvironments.mjs +169 -9
  25. package/dist/esm-node/builder/shared/builderPlugins/adapterBasic.mjs +41 -5
  26. package/dist/esm-node/builder/shared/builderPlugins/adapterSSR.mjs +3 -1
  27. package/dist/esm-node/plugins/deploy/index.mjs +10 -4
  28. package/dist/esm-node/plugins/deploy/platforms/cloudflare.mjs +178 -0
  29. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.mjs +438 -0
  30. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-fs-promises.mjs +7 -0
  31. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-loadable-server.mjs +185 -0
  32. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-path.mjs +59 -0
  33. package/dist/esm-node/rsbuild.mjs +5 -2
  34. package/dist/types/locale/en.d.ts +1 -1
  35. package/dist/types/locale/zh.d.ts +1 -1
  36. package/dist/types/plugins/deploy/index.d.ts +4 -1
  37. package/dist/types/plugins/deploy/platforms/cloudflare.d.ts +2 -0
  38. package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.d.mts +4 -0
  39. package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-fs-promises.d.mts +5 -0
  40. package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-loadable-server.d.mts +48 -0
  41. package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-path.d.mts +21 -0
  42. package/dist/types/types/config/deploy.d.ts +8 -0
  43. package/package.json +18 -17
@@ -1,5 +1,14 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
3
12
  (()=>{
4
13
  __webpack_require__.d = (exports1, definition)=>{
5
14
  for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
@@ -27,7 +36,37 @@ __webpack_require__.d(__webpack_exports__, {
27
36
  createAppBaselineConfig: ()=>createAppBaselineConfig,
28
37
  withAppBaseline: ()=>withAppBaseline
29
38
  });
39
+ const external_node_module_namespaceObject = require("node:module");
40
+ const external_node_path_namespaceObject = require("node:path");
41
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
30
42
  const cli_namespaceObject = require("@modern-js/plugin/cli");
43
+ const resolveReactRouterPackageDir = ()=>{
44
+ const localRequire = (0, external_node_module_namespaceObject.createRequire)(external_node_path_default().join(process.cwd(), 'package.json'));
45
+ try {
46
+ const reactRouterDomPackageJson = localRequire.resolve('react-router-dom/package.json', {
47
+ paths: [
48
+ process.cwd()
49
+ ]
50
+ });
51
+ const reactRouterPackageJson = localRequire.resolve('react-router/package.json', {
52
+ paths: [
53
+ external_node_path_default().dirname(reactRouterDomPackageJson)
54
+ ]
55
+ });
56
+ return external_node_path_default().dirname(reactRouterPackageJson);
57
+ } catch {
58
+ return;
59
+ }
60
+ };
61
+ const setReactRouterBridgeSafeAliases = (chain)=>{
62
+ const reactRouterPackageDir = resolveReactRouterPackageDir();
63
+ if (!reactRouterPackageDir) return;
64
+ const productionEntry = external_node_path_default().join(reactRouterPackageDir, 'dist/production/index.mjs');
65
+ const developmentEntry = external_node_path_default().join(reactRouterPackageDir, 'dist/development/index.mjs');
66
+ chain.resolve.alias.set('react-router$', productionEntry);
67
+ chain.resolve.alias.set('react-router/dist/production/index.js', productionEntry);
68
+ chain.resolve.alias.set('react-router/dist/development/index.js', developmentEntry);
69
+ };
31
70
  const createAppBaselineConfig = (options = {})=>{
32
71
  const { appId = 'app', enableBffRequestId = true, enableTelemetry = true, enableTelemetryExporters = true, otlpEndpoint = process.env.MODERN_TELEMETRY_OTLP_ENDPOINT || 'http://127.0.0.1:4318/v1/logs', victoriaMetricsEndpoint = process.env.MODERN_TELEMETRY_VICTORIA_ENDPOINT || 'http://127.0.0.1:8428/api/v1/import/prometheus', telemetryFailLoudStartup = true, enableModuleFederationSSR = true } = options;
33
72
  const server = {};
@@ -61,7 +100,10 @@ const createAppBaselineConfig = (options = {})=>{
61
100
  disableClientServer: true
62
101
  }
63
102
  },
64
- server
103
+ server,
104
+ tools: {
105
+ bundlerChain: setReactRouterBridgeSafeAliases
106
+ }
65
107
  };
66
108
  if (enableBffRequestId) baselineConfig.bff = {
67
109
  requestId: appId
@@ -1,5 +1,14 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
3
12
  (()=>{
4
13
  __webpack_require__.d = (exports1, definition)=>{
5
14
  for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
@@ -26,8 +35,61 @@ __webpack_require__.r(__webpack_exports__);
26
35
  __webpack_require__.d(__webpack_exports__, {
27
36
  getBuilderEnvironments: ()=>getBuilderEnvironments
28
37
  });
38
+ const external_node_fs_namespaceObject = require("node:fs");
39
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
40
+ const external_node_path_namespaceObject = require("node:path");
41
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
29
42
  const builder_namespaceObject = require("@modern-js/builder");
30
43
  const utils_namespaceObject = require("@modern-js/utils");
44
+ const BFF_EFFECT_WORKER_ENTRY_NAME = '__modern_bff_effect';
45
+ const BFF_EFFECT_WORKER_RUNTIME_QUERY = 'modern-bff-runtime';
46
+ const JS_OR_TS_EXTS = [
47
+ '.ts',
48
+ '.tsx',
49
+ '.js',
50
+ '.jsx',
51
+ '.mjs',
52
+ '.cjs'
53
+ ];
54
+ const CLOUDFLARE_WORKER_COMPAT_TEMPLATE_DIR = external_node_path_default().resolve(__dirname, '../../plugins/deploy/platforms/templates');
55
+ function findExistingFile(candidates) {
56
+ return candidates.find((candidate)=>external_node_fs_default().existsSync(candidate));
57
+ }
58
+ function resolvePackageEntry(packageName, paths) {
59
+ try {
60
+ return external_node_fs_default().realpathSync(require.resolve(packageName, {
61
+ paths
62
+ }));
63
+ } catch {
64
+ return;
65
+ }
66
+ }
67
+ function resolvePackageFile(packageName, filePath, paths) {
68
+ try {
69
+ const packageJsonPath = require.resolve(`${packageName}/package.json`, {
70
+ paths
71
+ });
72
+ const packageFile = external_node_path_default().join(external_node_path_default().dirname(packageJsonPath), filePath);
73
+ return external_node_fs_default().existsSync(packageFile) ? external_node_fs_default().realpathSync(packageFile) : void 0;
74
+ } catch {
75
+ return;
76
+ }
77
+ }
78
+ function setAliasIfPresent(alias, name, value) {
79
+ if (value) alias.set(name, value);
80
+ }
81
+ function getCloudflareWorkerCompatFile(file) {
82
+ return external_node_path_default().join(CLOUDFLARE_WORKER_COMPAT_TEMPLATE_DIR, file);
83
+ }
84
+ function getEffectBffEntry(normalizedConfig, appContext) {
85
+ if (!normalizedConfig.bff || 'hono' === normalizedConfig.bff.runtimeFramework) return;
86
+ const configuredEntry = normalizedConfig.bff.effect?.entry;
87
+ const entryWithoutExtension = configuredEntry ? external_node_path_default().isAbsolute(configuredEntry) ? configuredEntry : external_node_path_default().resolve(appContext.appDirectory, configuredEntry) : external_node_path_default().resolve(appContext.apiDirectory, 'effect', 'index');
88
+ return findExistingFile(JS_OR_TS_EXTS.map((extension)=>`${entryWithoutExtension}${extension}`));
89
+ }
90
+ function isCloudflareWorkerDeploy(normalizedConfig) {
91
+ return normalizedConfig.deploy?.target === 'cloudflare' || 'cloudflare' === process.env.MODERNJS_DEPLOY;
92
+ }
31
93
  function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig) {
32
94
  const entries = {};
33
95
  const { entrypoints = [], checkedEntries } = appContext;
@@ -44,6 +106,11 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
44
106
  const v = entries[entry];
45
107
  serverEntries[entry] = v.map((entry)=>entry.replace('index.jsx', 'index.server.jsx')).map((entry)=>entry.replace('bootstrap.jsx', 'bootstrap.server.jsx'));
46
108
  }
109
+ const cloudflareWorkerServerEntries = {};
110
+ for(const entry in entries){
111
+ const v = entries[entry];
112
+ cloudflareWorkerServerEntries[entry] = v.map((entry)=>entry.replace('index.jsx', 'index.server.jsx')).map((entry)=>entry.replace('bootstrap.jsx', 'index.server.jsx'));
113
+ }
47
114
  const environments = {
48
115
  client: {
49
116
  output: {
@@ -68,14 +135,114 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
68
135
  }
69
136
  };
70
137
  const useWorkerTarget = (0, utils_namespaceObject.isServiceWorker)(normalizedConfig);
71
- if (useWorkerTarget) environments[builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME] = {
72
- output: {
73
- target: 'web-worker'
74
- },
75
- source: {
76
- entry: serverEntries
77
- }
78
- };
138
+ if (useWorkerTarget) {
139
+ const useCloudflareModuleWorker = isCloudflareWorkerDeploy(normalizedConfig);
140
+ const effectBffEntry = useCloudflareModuleWorker ? getEffectBffEntry(normalizedConfig, appContext) : void 0;
141
+ const tanstackRouterSsrServerFile = useCloudflareModuleWorker ? resolvePackageFile('@tanstack/router-core', 'dist/esm/ssr/ssr-server.js', [
142
+ appContext.appDirectory,
143
+ process.cwd()
144
+ ]) : void 0;
145
+ const runtimeRscWorkerFile = useCloudflareModuleWorker ? resolvePackageFile('@modern-js/runtime', 'dist/esm/rsc/server.worker.mjs', [
146
+ appContext.appDirectory,
147
+ process.cwd()
148
+ ]) : void 0;
149
+ const renderRscWorkerFile = useCloudflareModuleWorker ? resolvePackageFile('@modern-js/render', 'dist/esm/rscWorker.mjs', [
150
+ appContext.appDirectory,
151
+ process.cwd()
152
+ ]) : void 0;
153
+ const reactFile = useCloudflareModuleWorker ? resolvePackageFile('react', 'index.js', [
154
+ appContext.appDirectory,
155
+ process.cwd()
156
+ ]) : void 0;
157
+ const reactJsxRuntimeFile = useCloudflareModuleWorker ? resolvePackageFile('react', 'jsx-runtime.js', [
158
+ appContext.appDirectory,
159
+ process.cwd()
160
+ ]) : void 0;
161
+ const reactJsxDevRuntimeFile = useCloudflareModuleWorker ? resolvePackageFile('react', 'jsx-dev-runtime.js', [
162
+ appContext.appDirectory,
163
+ process.cwd()
164
+ ]) : void 0;
165
+ const reactDomFile = useCloudflareModuleWorker ? resolvePackageFile('react-dom', 'index.js', [
166
+ appContext.appDirectory,
167
+ process.cwd()
168
+ ]) : void 0;
169
+ const reactDomServerEdgeFile = useCloudflareModuleWorker ? resolvePackageFile('react-dom', 'server.edge.js', [
170
+ appContext.appDirectory,
171
+ process.cwd()
172
+ ]) : void 0;
173
+ const loadableComponentFile = useCloudflareModuleWorker ? resolvePackageEntry('@loadable/component', [
174
+ appContext.appDirectory,
175
+ process.cwd(),
176
+ CLOUDFLARE_WORKER_COMPAT_TEMPLATE_DIR
177
+ ]) : void 0;
178
+ const loadableServerWorkerFile = useCloudflareModuleWorker ? getCloudflareWorkerCompatFile('cloudflare-worker-loadable-server.mjs') : void 0;
179
+ const fsPromisesWorkerFile = useCloudflareModuleWorker ? getCloudflareWorkerCompatFile('cloudflare-worker-fs-promises.mjs') : void 0;
180
+ const pathWorkerFile = useCloudflareModuleWorker ? getCloudflareWorkerCompatFile('cloudflare-worker-path.mjs') : void 0;
181
+ const baseWorkerEntries = useCloudflareModuleWorker ? cloudflareWorkerServerEntries : serverEntries;
182
+ const workerEntries = effectBffEntry ? {
183
+ ...baseWorkerEntries,
184
+ [BFF_EFFECT_WORKER_ENTRY_NAME]: [
185
+ `${effectBffEntry}?${BFF_EFFECT_WORKER_RUNTIME_QUERY}`
186
+ ]
187
+ } : baseWorkerEntries;
188
+ environments[builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME] = {
189
+ output: {
190
+ target: useCloudflareModuleWorker ? 'web' : 'web-worker',
191
+ ...useCloudflareModuleWorker ? {
192
+ module: true
193
+ } : {}
194
+ },
195
+ source: {
196
+ entry: workerEntries
197
+ },
198
+ tools: {
199
+ htmlPlugin: false,
200
+ ...useCloudflareModuleWorker ? {
201
+ bundlerChain: (chain)=>{
202
+ chain.merge({
203
+ experiments: {
204
+ outputModule: true
205
+ }
206
+ });
207
+ chain.target('webworker');
208
+ chain.plugins.delete('plugin-module-federation');
209
+ if (tanstackRouterSsrServerFile) {
210
+ chain.resolve.alias.set('@tanstack/router-core/ssr/server$', tanstackRouterSsrServerFile);
211
+ chain.resolve.alias.set('@tanstack/router-core/ssr/server', tanstackRouterSsrServerFile);
212
+ }
213
+ if (runtimeRscWorkerFile) {
214
+ chain.resolve.alias.set('@modern-js/runtime/rsc/server$', runtimeRscWorkerFile);
215
+ chain.resolve.alias.set('@modern-js/runtime/rsc/server', runtimeRscWorkerFile);
216
+ }
217
+ if (renderRscWorkerFile) {
218
+ chain.resolve.alias.set('@modern-js/render/rsc$', renderRscWorkerFile);
219
+ chain.resolve.alias.set('@modern-js/render/rsc', renderRscWorkerFile);
220
+ chain.resolve.alias.set('@modern-js/render/rsc-worker$', renderRscWorkerFile);
221
+ }
222
+ setAliasIfPresent(chain.resolve.alias, 'react$', reactFile);
223
+ setAliasIfPresent(chain.resolve.alias, 'react/jsx-runtime$', reactJsxRuntimeFile);
224
+ setAliasIfPresent(chain.resolve.alias, 'react/jsx-dev-runtime$', reactJsxDevRuntimeFile);
225
+ setAliasIfPresent(chain.resolve.alias, 'react-dom$', reactDomFile);
226
+ setAliasIfPresent(chain.resolve.alias, 'react-dom/server.edge$', reactDomServerEdgeFile);
227
+ setAliasIfPresent(chain.resolve.alias, '@loadable/component$', loadableComponentFile);
228
+ setAliasIfPresent(chain.resolve.alias, '@loadable/server$', loadableServerWorkerFile);
229
+ setAliasIfPresent(chain.resolve.alias, 'fs/promises$', fsPromisesWorkerFile);
230
+ setAliasIfPresent(chain.resolve.alias, 'node:fs/promises$', fsPromisesWorkerFile);
231
+ setAliasIfPresent(chain.resolve.alias, 'path$', pathWorkerFile);
232
+ setAliasIfPresent(chain.resolve.alias, 'node:path$', pathWorkerFile);
233
+ chain.resolve.alias.set('react-server-dom-rspack/server.node$', 'react-server-dom-rspack/server.edge');
234
+ chain.resolve.alias.set('react-server-dom-rspack/server.node', 'react-server-dom-rspack/server.edge');
235
+ chain.resolve.alias.set('react-server-dom-rspack/client.node$', 'react-server-dom-rspack/client.edge');
236
+ chain.resolve.alias.set('react-server-dom-rspack/client.node', 'react-server-dom-rspack/client.edge');
237
+ chain.resolve.fallback.set('async_hooks', false);
238
+ chain.resolve.fallback.set('node:async_hooks', false);
239
+ chain.resolve.fallback.set('fs', false);
240
+ chain.resolve.fallback.set('node:fs', false);
241
+ }
242
+ } : {}
243
+ }
244
+ };
245
+ }
79
246
  return {
80
247
  environments,
81
248
  builderConfig: tempBuilderConfig
@@ -43,8 +43,11 @@ const builderPluginAdapterBasic = (options)=>({
43
43
  setup (api) {
44
44
  api.modifyBundlerChain((chain, { target, CHAIN_ID, environment })=>{
45
45
  const isServiceWorker = environment.name === builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME;
46
- if ('node' === target || isServiceWorker) applyNodeCompat(isServiceWorker, chain);
47
- if ('web' === target) {
46
+ const isWebTargetServiceWorker = isServiceWorker && 'web' === target;
47
+ if ('node' === target || isServiceWorker) applyNodeCompat(isServiceWorker, chain, {
48
+ includeNodeExtensions: !isWebTargetServiceWorker
49
+ });
50
+ if ('web' === target && !isServiceWorker) {
48
51
  const bareServerModuleReg = /\.(server|node)\.[tj]sx?$/;
49
52
  const depExt = 'js';
50
53
  chain.module.rule(CHAIN_ID.RULE.JS).exclude.add(bareServerModuleReg);
@@ -60,8 +63,40 @@ const builderPluginAdapterBasic = (options)=>({
60
63
  });
61
64
  api.modifyRspackConfig((config, { target, environment })=>{
62
65
  const isServiceWorker = environment.name === builder_namespaceObject.SERVICE_WORKER_ENVIRONMENT_NAME;
66
+ const isWebTargetServiceWorker = isServiceWorker && 'web' === target;
63
67
  if ('node' === target || isServiceWorker) {
64
- const extensionAlias = {
68
+ const extensionAlias = isWebTargetServiceWorker ? {
69
+ '.js': [
70
+ '.worker.js',
71
+ '.server.js',
72
+ '.js'
73
+ ],
74
+ '.jsx': [
75
+ '.worker.jsx',
76
+ '.server.jsx',
77
+ '.jsx'
78
+ ],
79
+ '.ts': [
80
+ '.worker.ts',
81
+ '.server.ts',
82
+ '.ts'
83
+ ],
84
+ '.tsx': [
85
+ '.worker.tsx',
86
+ '.server.tsx',
87
+ '.tsx'
88
+ ],
89
+ '.mjs': [
90
+ '.worker.mjs',
91
+ '.server.mjs',
92
+ '.mjs'
93
+ ],
94
+ '.json': [
95
+ '.worker.json',
96
+ '.server.json',
97
+ '.json'
98
+ ]
99
+ } : {
65
100
  '.js': [
66
101
  '.node.js',
67
102
  '.server.js',
@@ -102,7 +137,8 @@ const builderPluginAdapterBasic = (options)=>({
102
137
  });
103
138
  }
104
139
  });
105
- function applyNodeCompat(isServiceWorker, chain) {
140
+ function applyNodeCompat(isServiceWorker, chain, options = {}) {
141
+ const { includeNodeExtensions = true } = options;
106
142
  const nodeExts = [
107
143
  '.node.js',
108
144
  '.node.jsx',
@@ -121,7 +157,7 @@ function applyNodeCompat(isServiceWorker, chain) {
121
157
  '.worker.ts',
122
158
  '.worker.tsx'
123
159
  ];
124
- for (const ext of nodeExts)chain.resolve.extensions.prepend(ext);
160
+ if (includeNodeExtensions) for (const ext of nodeExts)chain.resolve.extensions.prepend(ext);
125
161
  if (isServiceWorker) for (const ext of webWorkerExts)chain.resolve.extensions.prepend(ext);
126
162
  }
127
163
  exports.builderPluginAdapterBasic = __webpack_exports__.builderPluginAdapterBasic;
@@ -122,9 +122,10 @@ function applyFilterEntriesBySSRConfig({ isProd, chain, appNormalizedConfig }) {
122
122
  });
123
123
  }
124
124
  async function applySSRLoaderEntry(chain, optinos, isServer) {
125
- const { appContext } = optinos;
125
+ const { appContext, normalizedConfig } = optinos;
126
126
  const { internalDirectory } = appContext;
127
127
  const { entrypoints } = appContext;
128
+ const isRsc = (0, utils_namespaceObject.isUseRsc)(normalizedConfig);
128
129
  await Promise.all(entrypoints.map(async (entrypoint)=>{
129
130
  const { entryName } = entrypoint;
130
131
  const serverLoadersFile = (0, utils_js_namespaceObject.getServerCombinedModuleFile)(internalDirectory, entryName);
@@ -132,6 +133,7 @@ async function applySSRLoaderEntry(chain, optinos, isServer) {
132
133
  await utils_namespaceObject.fs.access(serverLoadersFile, utils_namespaceObject.fs.constants.F_OK);
133
134
  chain.entry(`${entryName}-server-loaders`).add(serverLoadersFile);
134
135
  } catch (err) {}
136
+ else if (isRsc) chain.entry(`${entryName}-server-loaders`).add("data:text/javascript,export%20{};");
135
137
  }));
136
138
  }
137
139
  function applySSRDataLoader(chain, options) {
@@ -24,9 +24,12 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- default: ()=>deploy
27
+ default: ()=>deploy,
28
+ getSupportedDeployTargets: ()=>getSupportedDeployTargets,
29
+ resolveDeployTarget: ()=>resolveDeployTarget
28
30
  });
29
31
  const external_std_env_namespaceObject = require("std-env");
32
+ const cloudflare_js_namespaceObject = require("./platforms/cloudflare.js");
30
33
  const gh_pages_js_namespaceObject = require("./platforms/gh-pages.js");
31
34
  const netlify_js_namespaceObject = require("./platforms/netlify.js");
32
35
  const node_js_namespaceObject = require("./platforms/node.js");
@@ -36,14 +39,18 @@ const deployPresets = {
36
39
  node: node_js_namespaceObject.createNodePreset,
37
40
  vercel: vercel_js_namespaceObject.createVercelPreset,
38
41
  netlify: netlify_js_namespaceObject.createNetlifyPreset,
39
- ghPages: gh_pages_js_namespaceObject.createGhPagesPreset
42
+ ghPages: gh_pages_js_namespaceObject.createGhPagesPreset,
43
+ cloudflare: cloudflare_js_namespaceObject.createCloudflarePreset
40
44
  };
45
+ const getSupportedDeployTargets = ()=>Object.keys(deployPresets);
46
+ const isDeployTarget = (target)=>Object.prototype.hasOwnProperty.call(deployPresets, target);
47
+ const resolveDeployTarget = (modernConfig, envDeployTarget = process.env.MODERNJS_DEPLOY, detectedProvider = external_std_env_namespaceObject.provider)=>modernConfig.deploy?.target || envDeployTarget || detectedProvider || 'node';
41
48
  async function getDeployPreset(appContext, modernConfig, deployTarget, api) {
42
49
  const { appDirectory, distDirectory, metaName } = appContext;
43
50
  const { useSSR, useAPI, useWebServer } = (0, index_js_namespaceObject.getProjectUsage)(appDirectory, distDirectory, metaName);
44
51
  const needModernServer = useSSR || useAPI || useWebServer;
52
+ if (!isDeployTarget(deployTarget)) throw new Error(`Unknown deploy target: '${deployTarget}'. deploy.target or MODERNJS_DEPLOY should be one of: ${getSupportedDeployTargets().join(', ')}.`);
45
53
  const createPreset = deployPresets[deployTarget];
46
- if (!createPreset) throw new Error(`Unknown deploy target: '${deployTarget}'. MODERNJS_DEPLOY should be 'node', 'vercel', or 'netlify'.`);
47
54
  return createPreset({
48
55
  appContext,
49
56
  modernConfig,
@@ -54,12 +61,12 @@ async function getDeployPreset(appContext, modernConfig, deployTarget, api) {
54
61
  const deploy = ()=>({
55
62
  name: '@modern-js/plugin-deploy',
56
63
  setup: (api)=>{
57
- const deployTarget = process.env.MODERNJS_DEPLOY || external_std_env_namespaceObject.provider || 'node';
58
64
  api.deploy(async ()=>{
59
65
  const appContext = api.getAppContext();
60
66
  const { metaName } = appContext;
61
- if ('modern-js' !== metaName && !process.env.MODERNJS_DEPLOY) return;
62
67
  const modernConfig = api.getNormalizedConfig();
68
+ const deployTarget = resolveDeployTarget(modernConfig);
69
+ if ('modern-js' !== metaName && !modernConfig.deploy?.target && !process.env.MODERNJS_DEPLOY) return;
63
70
  const deployPreset = await getDeployPreset(appContext, modernConfig, deployTarget, api);
64
71
  deployPreset?.prepare && await deployPreset?.prepare();
65
72
  deployPreset?.writeOutput && await deployPreset?.writeOutput();
@@ -69,8 +76,12 @@ const deploy = ()=>({
69
76
  }
70
77
  });
71
78
  exports["default"] = __webpack_exports__["default"];
79
+ exports.getSupportedDeployTargets = __webpack_exports__.getSupportedDeployTargets;
80
+ exports.resolveDeployTarget = __webpack_exports__.resolveDeployTarget;
72
81
  for(var __rspack_i in __webpack_exports__)if (-1 === [
73
- "default"
82
+ "default",
83
+ "getSupportedDeployTargets",
84
+ "resolveDeployTarget"
74
85
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
75
86
  Object.defineProperty(exports, '__esModule', {
76
87
  value: true
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, definition)=>{
14
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
+ enumerable: true,
16
+ get: definition[key]
17
+ });
18
+ };
19
+ })();
20
+ (()=>{
21
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
22
+ })();
23
+ (()=>{
24
+ __webpack_require__.r = (exports1)=>{
25
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
26
+ value: 'Module'
27
+ });
28
+ Object.defineProperty(exports1, '__esModule', {
29
+ value: true
30
+ });
31
+ };
32
+ })();
33
+ var __webpack_exports__ = {};
34
+ __webpack_require__.r(__webpack_exports__);
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ createCloudflarePreset: ()=>createCloudflarePreset
37
+ });
38
+ const external_node_path_namespaceObject = require("node:path");
39
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
40
+ const utils_namespaceObject = require("@modern-js/utils");
41
+ const index_js_namespaceObject = require("../utils/index.js");
42
+ const WORKER_ENTRY = 'server/index.mjs';
43
+ const WORKER_MANIFEST = 'server/modern-worker-manifest.json';
44
+ const ASSETS_BINDING = 'ASSETS';
45
+ const ROUTE_SPEC_FILE = 'route.json';
46
+ const ROUTE_SPEC_OUTPUT = `server/${ROUTE_SPEC_FILE}`;
47
+ const LOADABLE_STATS_FILE = 'loadable-stats.json';
48
+ const ROUTE_MANIFEST_FILE = 'routes-manifest.json';
49
+ const PUBLIC_ASSETS_DIRECTORY = 'public';
50
+ const WORKER_BUNDLE_DIRECTORY = 'worker';
51
+ const SERVER_BUNDLE_DIRECTORY = 'bundles';
52
+ const BFF_EFFECT_WORKER_ENTRY = `${WORKER_BUNDLE_DIRECTORY}/__modern_bff_effect.js`;
53
+ const getCompatibilityDate = ()=>new Date().toISOString().slice(0, 10);
54
+ const getWorkerName = (appDirectory)=>{
55
+ const basename = external_node_path_default().basename(appDirectory);
56
+ return basename.replace(/[^a-zA-Z0-9-_]/g, '-') || 'modern-cloudflare-worker';
57
+ };
58
+ const getConfiguredWorkerName = (appDirectory, modernConfig)=>{
59
+ const configuredName = modernConfig.deploy?.worker?.name?.trim();
60
+ return configuredName || getWorkerName(appDirectory);
61
+ };
62
+ const readRouteSpec = async (outputDirectory)=>{
63
+ const routeSpecPath = external_node_path_default().join(outputDirectory, ROUTE_SPEC_OUTPUT);
64
+ if (!await utils_namespaceObject.fs.pathExists(routeSpecPath)) return {
65
+ routes: []
66
+ };
67
+ const routeSpec = await utils_namespaceObject.fs.readJSON(routeSpecPath);
68
+ return {
69
+ ...routeSpec,
70
+ routes: Array.isArray(routeSpec.routes) ? routeSpec.routes : []
71
+ };
72
+ };
73
+ const createWorkerManifest = async (outputDirectory, modernConfig)=>{
74
+ const routeSpec = await readRouteSpec(outputDirectory);
75
+ const routes = await Promise.all(routeSpec.routes.map(async (route)=>{
76
+ const worker = 'string' == typeof route.worker ? route.worker : void 0;
77
+ return {
78
+ urlPath: route.urlPath,
79
+ entryName: route.entryName,
80
+ entryPath: route.entryPath,
81
+ isSSR: Boolean(route.isSSR),
82
+ worker,
83
+ workerExists: worker ? await utils_namespaceObject.fs.pathExists(external_node_path_default().join(outputDirectory, worker)) : false
84
+ };
85
+ }));
86
+ const bffPrefix = modernConfig.bff?.prefix;
87
+ const primaryBffPrefix = Array.isArray(bffPrefix) ? bffPrefix[0] : bffPrefix;
88
+ const isEffectBff = Boolean(modernConfig.bff) && modernConfig.bff?.runtimeFramework !== 'hono';
89
+ const effectBffWorkerExists = await utils_namespaceObject.fs.pathExists(external_node_path_default().join(outputDirectory, BFF_EFFECT_WORKER_ENTRY));
90
+ return {
91
+ version: 1,
92
+ runtime: {
93
+ type: 'cloudflare-module-worker',
94
+ entry: WORKER_ENTRY,
95
+ fetchExport: true,
96
+ nodeListen: false
97
+ },
98
+ assets: {
99
+ binding: ASSETS_BINDING,
100
+ directory: `./${PUBLIC_ASSETS_DIRECTORY}`,
101
+ runWorkerFirst: true
102
+ },
103
+ routeSpec: {
104
+ file: ROUTE_SPEC_OUTPUT,
105
+ routes
106
+ },
107
+ workerBundles: {
108
+ directory: WORKER_BUNDLE_DIRECTORY,
109
+ format: 'commonjs',
110
+ importableFromModuleWorker: true,
111
+ requestHandlerExport: 'requestHandler'
112
+ },
113
+ resources: {
114
+ loadableStats: LOADABLE_STATS_FILE,
115
+ routeManifest: ROUTE_MANIFEST_FILE
116
+ },
117
+ bff: isEffectBff && primaryBffPrefix && effectBffWorkerExists ? {
118
+ runtimeFramework: 'effect',
119
+ prefix: primaryBffPrefix,
120
+ worker: BFF_EFFECT_WORKER_ENTRY
121
+ } : void 0
122
+ };
123
+ };
124
+ const createWorkerModuleLoaders = (manifest)=>{
125
+ const imports = new Map();
126
+ for (const route of manifest.routeSpec.routes)if (route.worker && route.workerExists) {
127
+ const importPath = `../${String(route.worker).replace(/^\/+/u, '')}`;
128
+ imports.set(route.worker, `() => import(${JSON.stringify(importPath)})`);
129
+ }
130
+ if (manifest.bff?.worker) {
131
+ const importPath = `../${String(manifest.bff.worker).replace(/^\/+/u, '')}`;
132
+ imports.set(manifest.bff.worker, `() => import(${JSON.stringify(importPath)})`);
133
+ }
134
+ if (0 === imports.size) return '{}';
135
+ const loaders = [
136
+ ...imports.entries()
137
+ ].map(([worker, loader])=>`${JSON.stringify(worker)}: ${loader}`);
138
+ return `{\n${loaders.join(',\n')}\n}`;
139
+ };
140
+ const shouldCopyToPublicAssets = (src, distDirectory)=>{
141
+ const relativePath = external_node_path_default().relative(distDirectory, src);
142
+ if (!relativePath) return true;
143
+ const normalizedRelativePath = relativePath.replace(/\\/g, '/');
144
+ const [topLevelDirectory] = normalizedRelativePath.split('/');
145
+ return normalizedRelativePath !== ROUTE_SPEC_FILE && topLevelDirectory !== WORKER_BUNDLE_DIRECTORY && topLevelDirectory !== SERVER_BUNDLE_DIRECTORY;
146
+ };
147
+ const shouldCopyToWorkerBundle = (src, workerBundleDirectory)=>{
148
+ const relativePath = external_node_path_default().relative(workerBundleDirectory, src);
149
+ if (!relativePath) return true;
150
+ const normalizedRelativePath = relativePath.replace(/\\/g, '/');
151
+ const basename = external_node_path_default().basename(normalizedRelativePath);
152
+ if (basename.startsWith('.') || normalizedRelativePath.includes('/.')) return false;
153
+ return [
154
+ '.cjs',
155
+ '.js',
156
+ '.mjs'
157
+ ].includes(external_node_path_default().extname(normalizedRelativePath));
158
+ };
159
+ const createCloudflarePreset = ({ appContext, modernConfig })=>{
160
+ const { appDirectory, distDirectory } = appContext;
161
+ const outputDirectory = external_node_path_default().join(appDirectory, '.output');
162
+ const publicDirectory = external_node_path_default().join(outputDirectory, PUBLIC_ASSETS_DIRECTORY);
163
+ const workerEntryPath = external_node_path_default().join(outputDirectory, WORKER_ENTRY);
164
+ const workerManifestPath = external_node_path_default().join(outputDirectory, WORKER_MANIFEST);
165
+ const routeSpecOutputPath = external_node_path_default().join(outputDirectory, ROUTE_SPEC_OUTPUT);
166
+ const wranglerConfigPath = external_node_path_default().join(outputDirectory, 'wrangler.json');
167
+ const workerName = getConfiguredWorkerName(appDirectory, modernConfig);
168
+ return {
169
+ async prepare () {
170
+ await utils_namespaceObject.fs.remove(outputDirectory);
171
+ },
172
+ async writeOutput () {
173
+ await utils_namespaceObject.fs.copy(distDirectory, publicDirectory, {
174
+ filter: (src)=>shouldCopyToPublicAssets(src, distDirectory)
175
+ });
176
+ await utils_namespaceObject.fs.ensureDir(external_node_path_default().dirname(workerEntryPath));
177
+ await utils_namespaceObject.fs.ensureDir(external_node_path_default().dirname(workerManifestPath));
178
+ const routeSpecSourcePath = external_node_path_default().join(distDirectory, ROUTE_SPEC_FILE);
179
+ if (await utils_namespaceObject.fs.pathExists(routeSpecSourcePath)) await utils_namespaceObject.fs.copy(routeSpecSourcePath, routeSpecOutputPath);
180
+ const workerBundleSourceDirectory = external_node_path_default().join(distDirectory, WORKER_BUNDLE_DIRECTORY);
181
+ if (await utils_namespaceObject.fs.pathExists(workerBundleSourceDirectory)) await utils_namespaceObject.fs.copy(workerBundleSourceDirectory, external_node_path_default().join(outputDirectory, WORKER_BUNDLE_DIRECTORY), {
182
+ filter: (src)=>shouldCopyToWorkerBundle(src, workerBundleSourceDirectory)
183
+ });
184
+ await utils_namespaceObject.fs.writeJSON(wranglerConfigPath, {
185
+ $schema: 'node_modules/wrangler/config-schema.json',
186
+ name: workerName,
187
+ main: WORKER_ENTRY,
188
+ compatibility_date: getCompatibilityDate(),
189
+ compatibility_flags: [
190
+ 'nodejs_compat',
191
+ 'global_fetch_strictly_public'
192
+ ],
193
+ assets: {
194
+ directory: `./${PUBLIC_ASSETS_DIRECTORY}`,
195
+ binding: ASSETS_BINDING,
196
+ run_worker_first: true
197
+ }
198
+ }, {
199
+ spaces: 2
200
+ });
201
+ await utils_namespaceObject.fs.writeJSON(workerManifestPath, await createWorkerManifest(outputDirectory, modernConfig), {
202
+ spaces: 2
203
+ });
204
+ await utils_namespaceObject.fs.writeJSON(external_node_path_default().join(outputDirectory, 'package.json'), {
205
+ type: 'commonjs'
206
+ });
207
+ },
208
+ async genEntry () {
209
+ const template = await (0, index_js_namespaceObject.readTemplate)('cloudflare-entry.mjs');
210
+ const manifest = await utils_namespaceObject.fs.readJSON(workerManifestPath);
211
+ await utils_namespaceObject.fs.writeFile(workerEntryPath, template.replace('p_workerManifest', JSON.stringify(manifest, null, 2)).replace('p_workerModuleLoaders', createWorkerModuleLoaders(manifest)));
212
+ }
213
+ };
214
+ };
215
+ exports.createCloudflarePreset = __webpack_exports__.createCloudflarePreset;
216
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
217
+ "createCloudflarePreset"
218
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
219
+ Object.defineProperty(exports, '__esModule', {
220
+ value: true
221
+ });