@modern-js/server 1.1.1 → 1.1.3-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/js/modern/libs/hook-api/route.js +37 -0
  3. package/dist/js/modern/libs/{hook-api.js → hook-api/template.js} +0 -0
  4. package/dist/js/modern/libs/route/index.js +4 -0
  5. package/dist/js/modern/libs/route/matcher.js +5 -1
  6. package/dist/js/modern/libs/serve-file.js +23 -25
  7. package/dist/js/modern/server/{web-server.js → dev-server/dev-server-split.js} +9 -7
  8. package/dist/js/modern/server/{dev-server.js → dev-server/dev-server.js} +41 -22
  9. package/dist/js/modern/server/dev-server/index.js +2 -0
  10. package/dist/js/modern/server/index.js +61 -62
  11. package/dist/js/modern/server/{api-server.js → modern-server-split.js} +6 -10
  12. package/dist/js/modern/server/modern-server.js +78 -25
  13. package/dist/js/modern/utils.js +2 -2
  14. package/dist/js/node/libs/hook-api/route.js +46 -0
  15. package/dist/js/node/libs/{hook-api.js → hook-api/template.js} +0 -0
  16. package/dist/js/node/libs/route/index.js +4 -0
  17. package/dist/js/node/libs/route/matcher.js +5 -1
  18. package/dist/js/node/libs/serve-file.js +25 -26
  19. package/dist/js/node/server/{api-server.js → dev-server/dev-server-split.js} +7 -12
  20. package/dist/js/node/server/{dev-server.js → dev-server/dev-server.js} +42 -21
  21. package/dist/js/node/server/dev-server/index.js +27 -0
  22. package/dist/js/node/server/index.js +67 -63
  23. package/dist/js/node/server/{web-server.js → modern-server-split.js} +10 -9
  24. package/dist/js/node/server/modern-server.js +80 -25
  25. package/dist/js/node/utils.js +2 -2
  26. package/dist/types/libs/hook-api/route.d.ts +13 -0
  27. package/dist/types/libs/{hook-api.d.ts → hook-api/template.d.ts} +0 -0
  28. package/dist/types/libs/route/index.d.ts +1 -0
  29. package/dist/types/libs/route/matcher.d.ts +1 -0
  30. package/dist/types/libs/serve-file.d.ts +1 -1
  31. package/dist/types/server/{api-server.d.ts → dev-server/dev-server-split.d.ts} +7 -8
  32. package/dist/types/server/{dev-server.d.ts → dev-server/dev-server.d.ts} +6 -5
  33. package/dist/types/server/dev-server/index.d.ts +2 -0
  34. package/dist/types/server/index.d.ts +3 -1
  35. package/dist/types/server/{web-server.d.ts → modern-server-split.d.ts} +5 -4
  36. package/dist/types/server/modern-server.d.ts +7 -5
  37. package/dist/types/utils.d.ts +1 -1
  38. package/package.json +19 -17
  39. package/src/libs/hook-api/route.ts +38 -0
  40. package/src/libs/{hook-api.ts → hook-api/template.ts} +0 -0
  41. package/src/libs/route/index.ts +4 -0
  42. package/src/libs/route/matcher.ts +5 -1
  43. package/src/libs/serve-file.ts +16 -20
  44. package/src/server/{api-server.ts → dev-server/dev-server-split.ts} +9 -11
  45. package/src/server/{dev-server.ts → dev-server/dev-server.ts} +56 -23
  46. package/src/server/dev-server/index.ts +2 -0
  47. package/src/server/index.ts +69 -46
  48. package/src/server/{web-server.ts → modern-server-split.ts} +12 -10
  49. package/src/server/modern-server.ts +87 -40
  50. package/src/utils.ts +2 -2
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable max-lines */
2
- import { IncomingMessage, ServerResponse, Server } from 'http';
2
+ import { IncomingMessage, ServerResponse, Server, createServer } from 'http';
3
3
  import util from 'util';
4
4
  import path from 'path';
5
5
  import { fs, ROUTE_SPEC_FILE } from '@modern-js/utils';
6
- import { Adapter } from '@modern-js/server-plugin';
7
- import { gather, createMiddlewareCollecter } from '@modern-js/server-utils';
6
+ import { Adapter, APIServerStartInput } from '@modern-js/server-plugin';
7
+ import { createMiddlewareCollecter } from '@modern-js/server-utils';
8
8
  import type { NormalizedConfig } from '@modern-js/core';
9
9
  import mime from 'mime-types';
10
10
  import axios from 'axios';
@@ -30,7 +30,8 @@ import {
30
30
  ERROR_DIGEST,
31
31
  ERROR_PAGE_TEXT,
32
32
  } from '@/constants';
33
- import { createTemplateAPI } from '@/libs/hook-api';
33
+ import { createTemplateAPI } from '@/libs/hook-api/template';
34
+ import { createRouteAPI } from '@/libs/hook-api/route';
34
35
 
35
36
  type ModernServerHandler = (
36
37
  context: ModernServerContext,
@@ -63,12 +64,12 @@ export class ModernServer {
63
64
 
64
65
  protected presetRoutes?: ModernRouteInterface[];
65
66
 
67
+ protected runner!: ServerHookRunner;
68
+
66
69
  protected readonly logger: Logger;
67
70
 
68
71
  protected readonly measure: Measure;
69
72
 
70
- private readonly runner: ServerHookRunner;
71
-
72
73
  private readonly isDev: boolean = false;
73
74
 
74
75
  private staticFileHandler!: ReturnType<typeof createStaticFileHandler>;
@@ -85,18 +86,15 @@ export class ModernServer {
85
86
 
86
87
  private proxyHandler: ReturnType<typeof createProxyHandler> = null;
87
88
 
88
- constructor(
89
- {
90
- pwd,
91
- config,
92
- dev,
93
- routes,
94
- staticGenerate,
95
- logger,
96
- measure,
97
- }: ModernServerOptions,
98
- runner: ServerHookRunner,
99
- ) {
89
+ constructor({
90
+ pwd,
91
+ config,
92
+ dev,
93
+ routes,
94
+ staticGenerate,
95
+ logger,
96
+ measure,
97
+ }: ModernServerOptions) {
100
98
  require('ignore-styles');
101
99
  this.isDev = Boolean(dev);
102
100
 
@@ -104,7 +102,6 @@ export class ModernServer {
104
102
  this.distDir = path.join(pwd, config.output.path || '');
105
103
  this.workDir = this.isDev ? pwd : this.distDir;
106
104
  this.conf = config;
107
- this.runner = runner;
108
105
  this.logger = logger!;
109
106
  this.measure = measure!;
110
107
  this.router = new RouteMatchManager();
@@ -122,7 +119,9 @@ export class ModernServer {
122
119
  }
123
120
 
124
121
  // server prepare
125
- public async init() {
122
+ public async init(runner: ServerHookRunner) {
123
+ this.runner = runner;
124
+
126
125
  const { distDir, isDev, staticGenerate, conf } = this;
127
126
 
128
127
  this.addHandler((ctx: ModernServerContext, next: NextFunction) => {
@@ -154,14 +153,20 @@ export class ModernServer {
154
153
 
155
154
  await this.prepareFrameHandler();
156
155
 
156
+ const { favicon, faviconByEntries } = this.conf.output;
157
+ const favicons = this.prepareFavicons(favicon, faviconByEntries);
158
+ // Only work when without setting `assetPrefix`.
159
+ // Setting `assetPrefix` means these resources should be uploaded to CDN.
160
+ const staticPathRegExp = new RegExp(
161
+ `^/(static/|upload/|favicon.ico|icon.png${
162
+ favicons.length > 0 ? `|${favicons.join('|')}` : ''
163
+ })`,
164
+ );
165
+
157
166
  this.staticFileHandler = createStaticFileHandler([
158
167
  {
159
- path: '/static/',
160
- target: path.join(distDir, 'static'),
161
- },
162
- {
163
- path: '/upload/',
164
- target: path.join(distDir, 'upload'),
168
+ path: staticPathRegExp,
169
+ target: distDir,
165
170
  },
166
171
  ]);
167
172
 
@@ -192,6 +197,16 @@ export class ModernServer {
192
197
  reader.close();
193
198
  }
194
199
 
200
+ public async createHTTPServer(
201
+ handler: (
202
+ req: IncomingMessage,
203
+ res: ServerResponse,
204
+ next?: () => void,
205
+ ) => void,
206
+ ) {
207
+ return createServer(handler);
208
+ }
209
+
195
210
  // warmup ssr function
196
211
  protected warmupSSRBundle() {
197
212
  const { distDir } = this;
@@ -235,9 +250,6 @@ export class ModernServer {
235
250
  protected async prepareFrameHandler() {
236
251
  const { workDir, runner } = this;
237
252
 
238
- // inner tool, gather user inject
239
- const { api: userAPIExt, web: userWebExt } = gather(workDir);
240
-
241
253
  // server hook, gather plugin inject
242
254
  const { getMiddlewares, ...collector } = createMiddlewareCollecter();
243
255
 
@@ -249,7 +261,7 @@ export class ModernServer {
249
261
 
250
262
  // get api or web server handler from server-framework plugin
251
263
  if (await fs.pathExists(path.join(serverDir))) {
252
- const webExtension = mergeExtension(pluginWebExt, userWebExt);
264
+ const webExtension = mergeExtension(pluginWebExt);
253
265
  this.frameWebHandler = await this.prepareWebHandler(webExtension);
254
266
  }
255
267
 
@@ -259,11 +271,11 @@ export class ModernServer {
259
271
  : ApiServerMode.func;
260
272
 
261
273
  // if use lambda/, mean framework style of writing, then discard user extension
262
- const apiExtension = mergeExtension(
263
- pluginAPIExt,
264
- mode === ApiServerMode.frame ? [] : userAPIExt,
265
- );
266
- this.frameAPIHandler = await this.prepareAPIHandler(mode, apiExtension);
274
+ const apiExtension = mergeExtension(pluginAPIExt);
275
+ this.frameAPIHandler = await this.prepareAPIHandler(mode, {
276
+ ...apiExtension,
277
+ modernJsConfig: this.conf,
278
+ });
267
279
  }
268
280
  }
269
281
 
@@ -284,7 +296,7 @@ export class ModernServer {
284
296
 
285
297
  protected async prepareAPIHandler(
286
298
  mode: ApiServerMode,
287
- extension: ReturnType<typeof mergeExtension>,
299
+ extension: APIServerStartInput['config'],
288
300
  ) {
289
301
  const { workDir, runner, conf } = this;
290
302
  const { bff } = conf as ConfWithBFF;
@@ -295,7 +307,7 @@ export class ModernServer {
295
307
  pwd: workDir,
296
308
  mode,
297
309
  config: extension,
298
- prefix,
310
+ prefix: Array.isArray(prefix) ? prefix[0] : prefix,
299
311
  },
300
312
  { onLast: () => null as any },
301
313
  );
@@ -310,11 +322,32 @@ export class ModernServer {
310
322
  const preMiddleware: ModernServerAsyncHandler[] =
311
323
  await this.runner.preServerInit(conf);
312
324
 
313
- preMiddleware.forEach(mid => {
325
+ preMiddleware.flat().forEach(mid => {
314
326
  this.addHandler(mid);
315
327
  });
316
328
  }
317
329
 
330
+ private prepareFavicons(
331
+ favicon: string | undefined,
332
+ faviconByEntries?: Record<string, string | undefined>,
333
+ ) {
334
+ const faviconNames = [];
335
+ if (favicon) {
336
+ faviconNames.push(favicon.substring(favicon.lastIndexOf('/') + 1));
337
+ }
338
+ if (faviconByEntries) {
339
+ Object.keys(faviconByEntries).forEach(f => {
340
+ const curFavicon = faviconByEntries[f];
341
+ if (curFavicon) {
342
+ faviconNames.push(
343
+ curFavicon.substring(curFavicon.lastIndexOf('/') + 1),
344
+ );
345
+ }
346
+ });
347
+ }
348
+ return faviconNames;
349
+ }
350
+
318
351
  /* —————————————————————— private function —————————————————————— */
319
352
 
320
353
  // handler route.json, include api / csr / ssr
@@ -322,6 +355,8 @@ export class ModernServer {
322
355
  private async routeHandler(context: ModernServerContext) {
323
356
  const { req, res } = context;
324
357
 
358
+ await this.runner.beforeMatch({ context }, { onLast: noop as any });
359
+
325
360
  // match routes in the route spec
326
361
  const matched = this.router.match(context.url);
327
362
  if (!matched) {
@@ -329,8 +364,19 @@ export class ModernServer {
329
364
  return;
330
365
  }
331
366
 
332
- const route = matched.generate();
333
- const params = matched.parseURLParams(context.url);
367
+ const routeAPI = createRouteAPI(matched, this.router);
368
+ await this.runner.afterMatch(
369
+ { context, routeAPI },
370
+ { onLast: noop as any },
371
+ );
372
+
373
+ if (res.headersSent) {
374
+ return;
375
+ }
376
+
377
+ const { current } = routeAPI as any;
378
+ const route = current.generate();
379
+ const params = current.parseURLParams(context.url);
334
380
  context.setParams(params);
335
381
 
336
382
  // route is api service
@@ -352,6 +398,7 @@ export class ModernServer {
352
398
  return;
353
399
  }
354
400
 
401
+ await this.runner.beforeRender({ context }, { onLast: noop as any });
355
402
  const file = await this.routeRenderHandler(context, route);
356
403
  if (!file) {
357
404
  this.render404(context);
package/src/utils.ts CHANGED
@@ -1,6 +1,6 @@
1
- export const mergeExtension = (users: any[], plugins: any[]) => {
1
+ export const mergeExtension = (users: any[]) => {
2
2
  const output: any[] = [];
3
- return { middleware: output.concat(users).concat(plugins) };
3
+ return { middleware: output.concat(users) };
4
4
  };
5
5
 
6
6
  export const toMessage = (dig: string, e: Error | string): string => {