@modern-js/server 1.3.1 → 1.3.2

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 (52) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +9 -9
  3. package/src/constants.ts +0 -26
  4. package/src/dev-tools/babel/register.ts +0 -37
  5. package/src/dev-tools/dev-server-plugin.ts +0 -48
  6. package/src/dev-tools/https/global.d.ts +0 -3
  7. package/src/dev-tools/https/index.ts +0 -12
  8. package/src/dev-tools/launch-editor/index.ts +0 -29
  9. package/src/dev-tools/mock/getMockData.ts +0 -109
  10. package/src/dev-tools/mock/index.ts +0 -63
  11. package/src/dev-tools/socket-server.ts +0 -192
  12. package/src/dev-tools/watcher/dependency-tree.ts +0 -94
  13. package/src/dev-tools/watcher/index.ts +0 -79
  14. package/src/dev-tools/watcher/stats-cache.ts +0 -53
  15. package/src/index.ts +0 -16
  16. package/src/libs/context/context.ts +0 -176
  17. package/src/libs/context/index.ts +0 -7
  18. package/src/libs/hook-api/route.ts +0 -38
  19. package/src/libs/hook-api/template.ts +0 -53
  20. package/src/libs/metrics.ts +0 -15
  21. package/src/libs/proxy.ts +0 -85
  22. package/src/libs/render/cache/__tests__/cache.fun.test.ts +0 -94
  23. package/src/libs/render/cache/__tests__/cache.test.ts +0 -240
  24. package/src/libs/render/cache/__tests__/cacheable.ts +0 -44
  25. package/src/libs/render/cache/__tests__/error-configuration.ts +0 -34
  26. package/src/libs/render/cache/__tests__/matched-cache.ts +0 -88
  27. package/src/libs/render/cache/index.ts +0 -75
  28. package/src/libs/render/cache/page-caches/index.ts +0 -11
  29. package/src/libs/render/cache/page-caches/lru.ts +0 -38
  30. package/src/libs/render/cache/spr.ts +0 -301
  31. package/src/libs/render/cache/type.ts +0 -59
  32. package/src/libs/render/cache/util.ts +0 -97
  33. package/src/libs/render/index.ts +0 -78
  34. package/src/libs/render/modern/browser-list.ts +0 -7
  35. package/src/libs/render/modern/index.ts +0 -41
  36. package/src/libs/render/modern/module.d.ts +0 -4
  37. package/src/libs/render/reader.ts +0 -119
  38. package/src/libs/render/ssr.ts +0 -62
  39. package/src/libs/render/static.ts +0 -52
  40. package/src/libs/render/type.ts +0 -38
  41. package/src/libs/route/index.ts +0 -77
  42. package/src/libs/route/matcher.ts +0 -93
  43. package/src/libs/route/route.ts +0 -32
  44. package/src/libs/serve-file.ts +0 -34
  45. package/src/server/dev-server/dev-server-split.ts +0 -41
  46. package/src/server/dev-server/dev-server.ts +0 -300
  47. package/src/server/dev-server/index.ts +0 -2
  48. package/src/server/index.ts +0 -163
  49. package/src/server/modern-server-split.ts +0 -97
  50. package/src/server/modern-server.ts +0 -636
  51. package/src/type.ts +0 -88
  52. package/src/utils.ts +0 -79
@@ -1,300 +0,0 @@
1
- import http, {
2
- Server,
3
- createServer,
4
- IncomingMessage,
5
- ServerResponse,
6
- } from 'http';
7
- import path from 'path';
8
- import { createServer as createHttpsServer } from 'https';
9
- import {
10
- API_DIR,
11
- HMR_SOCK_PATH,
12
- SERVER_DIR,
13
- SHARED_DIR,
14
- } from '@modern-js/utils';
15
- import type { MultiCompiler, Compiler } from 'webpack';
16
- import webpackDevMiddleware from 'webpack-dev-middleware';
17
- import { ModernServer } from '../modern-server';
18
- import { createMockHandler } from '../../dev-tools/mock';
19
- import { createProxyHandler, ProxyOptions } from '../../libs/proxy';
20
- import {
21
- DevServerOptions,
22
- ModernServerOptions,
23
- NextFunction,
24
- ServerHookRunner,
25
- ReadyOptions,
26
- } from '../../type';
27
- import SocketServer from '../../dev-tools/socket-server';
28
- import DevServerPlugin from '../../dev-tools/dev-server-plugin';
29
- import { ModernServerContext } from '../../libs/context';
30
- import { createLaunchEditorHandler } from '../../dev-tools/launch-editor';
31
- import { enableRegister } from '../../dev-tools/babel/register';
32
- import * as reader from '../../libs/render/reader';
33
- import Watcher from '../../dev-tools/watcher';
34
- import { AGGRED_DIR } from '../../constants';
35
-
36
- const DEFAULT_DEV_OPTIONS: DevServerOptions = {
37
- client: {
38
- port: '8080',
39
- overlay: false,
40
- logging: 'none',
41
- path: HMR_SOCK_PATH,
42
- host: 'localhost',
43
- },
44
- https: false,
45
- dev: { writeToDisk: true },
46
- watch: true,
47
- hot: true,
48
- liveReload: true,
49
- };
50
-
51
- export class ModernDevServer extends ModernServer {
52
- private devProxyHandler: ReturnType<typeof createProxyHandler> = null;
53
-
54
- private mockHandler: ReturnType<typeof createMockHandler> = null;
55
-
56
- private readonly dev: DevServerOptions;
57
-
58
- private readonly compiler?: MultiCompiler | Compiler;
59
-
60
- private socketServer!: SocketServer;
61
-
62
- private watcher!: Watcher;
63
-
64
- private devMiddleware!: webpackDevMiddleware.API<
65
- http.IncomingMessage,
66
- http.ServerResponse
67
- >;
68
-
69
- constructor(options: ModernServerOptions) {
70
- super(options);
71
-
72
- // set webpack compiler
73
- this.compiler = options.compiler!;
74
-
75
- // set dev server options, like webpack-dev-server
76
- this.dev =
77
- typeof options.dev === 'boolean'
78
- ? DEFAULT_DEV_OPTIONS
79
- : { ...DEFAULT_DEV_OPTIONS, ...options.dev };
80
-
81
- enableRegister(this.pwd, this.conf);
82
- }
83
-
84
- // Complete the preparation of services
85
- public async init(runner: ServerHookRunner) {
86
- const { conf, pwd, compiler } = this;
87
- // mock handler
88
- this.mockHandler = createMockHandler({ pwd });
89
- this.addHandler((ctx: ModernServerContext, next: NextFunction) => {
90
- ctx.res.setHeader('Access-Control-Allow-Origin', '*');
91
- ctx.res.setHeader('Access-Control-Allow-Credentials', 'false');
92
-
93
- if (this.mockHandler) {
94
- this.mockHandler(ctx, next);
95
- } else {
96
- next();
97
- }
98
- });
99
-
100
- // dev proxy handler, each proxy has own handler
101
- this.devProxyHandler = createProxyHandler(
102
- conf.tools?.devServer?.proxy as ProxyOptions,
103
- );
104
- if (this.devProxyHandler) {
105
- this.devProxyHandler.forEach(handler => {
106
- this.addHandler(handler);
107
- });
108
- }
109
-
110
- // do webpack build / plugin apply / socket server when pass compiler instance
111
- if (compiler) {
112
- // init socket server
113
- this.socketServer = new SocketServer(this.dev);
114
-
115
- // open file in edtor.
116
- this.addHandler(createLaunchEditorHandler());
117
-
118
- // setup compiler in server, also add dev-middleware to handler static file in memory
119
- const devMiddlewareHandler = this.setupCompiler(compiler);
120
- this.addHandler(devMiddlewareHandler);
121
- }
122
-
123
- await super.init(runner);
124
-
125
- // watch mock/ server/ api/ dir file change
126
- if (this.dev.watch) {
127
- this.startWatcher();
128
- }
129
- }
130
-
131
- public ready(options: ReadyOptions = {}) {
132
- // reset the routing management instance every times the service starts
133
- this.router.reset(
134
- this.filterRoutes(options.routes || this.presetRoutes || []),
135
- );
136
- this.cleanSSRCache();
137
-
138
- // reset static file
139
- reader.updateFile();
140
-
141
- this.runner.reset();
142
- }
143
-
144
- public onListening(app: Server) {
145
- this.socketServer?.prepare(app);
146
- }
147
-
148
- public async close() {
149
- super.close();
150
- await this.watcher.close();
151
- await new Promise<void>(resolve => {
152
- if (this.devMiddleware) {
153
- this.devMiddleware.close(() => {
154
- resolve();
155
- });
156
- } else {
157
- resolve();
158
- }
159
- });
160
- }
161
-
162
- public async createHTTPServer(
163
- handler: (
164
- req: IncomingMessage,
165
- res: ServerResponse,
166
- next?: () => void,
167
- ) => void,
168
- ) {
169
- const { dev } = this;
170
- const devHttpsOption = typeof dev === 'object' && dev.https;
171
- if (devHttpsOption) {
172
- const { genHttpsOptions } = require('../../dev-tools/https');
173
- const httpsOptions = await genHttpsOptions(devHttpsOption);
174
- return createHttpsServer(httpsOptions, handler);
175
- } else {
176
- return createServer(handler);
177
- }
178
- }
179
-
180
- // set up plugin to each compiler
181
- // register hooks for each compilation, update socket stats if recompiled
182
- // start dev middleware
183
- private setupCompiler(compiler: MultiCompiler | Compiler) {
184
- this.setupDevServerPlugin(compiler);
185
- this.setupHooks();
186
- return this.setupDevMiddleware(compiler);
187
- }
188
-
189
- private setupDevServerPlugin(compiler: MultiCompiler | Compiler) {
190
- const { dev: devConf } = this;
191
- if ((compiler as MultiCompiler).compilers) {
192
- (compiler as MultiCompiler).compilers.forEach(target => {
193
- if (target.name === 'client') {
194
- new DevServerPlugin(devConf).apply(target);
195
- }
196
- });
197
- } else {
198
- new DevServerPlugin(devConf).apply(compiler as Compiler);
199
- }
200
- }
201
-
202
- private setupHooks() {
203
- const invalidPlugin = () => {
204
- this.socketServer.sockWrite('invalid');
205
- };
206
-
207
- const addHooks = (compiler: Compiler) => {
208
- const { compile, invalid, done } = compiler.hooks;
209
-
210
- compile.tap('modern-dev-server', invalidPlugin);
211
- invalid.tap('modern-dev-server', invalidPlugin);
212
- done.tap('modern-dev-server', (stats: any) => {
213
- this.socketServer.updateStats(stats);
214
-
215
- // Reset only when client compile done
216
- if (stats.toJson({ all: false }).name === 'client') {
217
- this.ready({ routes: this.readRouteSpec() });
218
- }
219
- });
220
- };
221
-
222
- if ((this.compiler as MultiCompiler).compilers) {
223
- (this.compiler as MultiCompiler).compilers.forEach(addHooks);
224
- } else {
225
- addHooks(this.compiler as Compiler);
226
- }
227
- }
228
-
229
- private setupDevMiddleware(compiler: MultiCompiler | Compiler) {
230
- this.devMiddleware = webpackDevMiddleware(compiler, {
231
- publicPath: '/',
232
- writeToDisk: this.dev.dev.writeToDisk,
233
- stats: false,
234
- });
235
-
236
- return (ctx: ModernServerContext, next: NextFunction) => {
237
- const { req, res } = ctx;
238
- this.devMiddleware(req, res, next);
239
- };
240
- }
241
-
242
- private cleanSSRCache() {
243
- const { distDir } = this;
244
- const bundles = this.router.getBundles();
245
-
246
- bundles.forEach(bundle => {
247
- const filepath = path.join(distDir, bundle as string);
248
- if (require.cache[filepath]) {
249
- delete require.cache[filepath];
250
- }
251
- });
252
- }
253
-
254
- private startWatcher() {
255
- const { pwd } = this;
256
- const { mock } = AGGRED_DIR;
257
- const defaultWatched = [
258
- `${mock}/**/*`,
259
- `${SERVER_DIR}/**/*`,
260
- `${API_DIR}/**`,
261
- `${SHARED_DIR}/**/*`,
262
- ];
263
-
264
- const defaultWatchedPaths = defaultWatched.map(p =>
265
- path.normalize(path.join(pwd, p)),
266
- );
267
- const mockPath = path.normalize(path.join(pwd, mock));
268
-
269
- const watcher = new Watcher();
270
- watcher.createDepTree();
271
-
272
- // 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
273
- watcher.listen(
274
- defaultWatchedPaths,
275
- {
276
- // 初始化的时候不触发 add、addDir 事件
277
- ignoreInitial: true,
278
- ignored: /api\/typings\/.*/,
279
- },
280
- (filepath: string) => {
281
- watcher.updateDepTree();
282
- watcher.cleanDepCache(filepath);
283
-
284
- this.runner.reset();
285
-
286
- if (filepath.startsWith(mockPath)) {
287
- this.mockHandler = createMockHandler({ pwd });
288
- } else {
289
- try {
290
- this.prepareFrameHandler();
291
- } catch (e) {
292
- this.logger.error(e as Error);
293
- }
294
- }
295
- },
296
- );
297
-
298
- this.watcher = watcher;
299
- }
300
- }
@@ -1,2 +0,0 @@
1
- export { ModernAPIDevServer, ModernSSRDevServer } from './dev-server-split';
2
- export { ModernDevServer } from './dev-server';
@@ -1,163 +0,0 @@
1
- import { IncomingMessage, ServerResponse, Server as httpServer } from 'http';
2
- import path from 'path';
3
- import { serverManager } from '@modern-js/server-plugin';
4
- import { logger as defaultLogger } from '@modern-js/utils';
5
- import {
6
- AppContext,
7
- initAppContext,
8
- initAppDir,
9
- loadUserConfig,
10
- ConfigContext,
11
- UserConfig,
12
- } from '@modern-js/core';
13
- import { ModernServerOptions, ServerHookRunner, ReadyOptions } from '../type';
14
- import { metrics as defaultMetrics } from '../libs/metrics';
15
- import { ModernServer } from './modern-server';
16
- import type { ModernDevServer } from './dev-server';
17
- import {
18
- ModernAPIServer,
19
- ModernSSRServer,
20
- ModernWebServer,
21
- } from './modern-server-split';
22
-
23
- export class Server {
24
- public options: ModernServerOptions;
25
-
26
- private server!: ModernServer | ModernDevServer;
27
-
28
- private app!: httpServer;
29
-
30
- private runner!: ServerHookRunner;
31
-
32
- constructor(options: ModernServerOptions) {
33
- this.options = options;
34
- }
35
-
36
- public getRequestHandler() {
37
- return (req: IncomingMessage, res: ServerResponse, next?: () => void) => {
38
- const requestHandler = this.server.getRequestHandler();
39
- return requestHandler(req, res, next);
40
- };
41
- }
42
-
43
- public ready(readyOptions: ReadyOptions = {}) {
44
- this.server.ready(readyOptions);
45
- }
46
-
47
- public async init() {
48
- const { options } = this;
49
-
50
- options.logger = options.logger || defaultLogger;
51
- options.metrics = options.metrics || defaultMetrics;
52
-
53
- // initialize server
54
- if (options.dev) {
55
- this.server = this.createDevServer();
56
- } else {
57
- this.server = this.createProdServer();
58
- }
59
- // check if https is configured when start dev server
60
- this.app = await this.server.createHTTPServer(this.getRequestHandler());
61
-
62
- this.runner = await this.createHookRunner();
63
-
64
- // runner can only be used after server init
65
- await this.server.init(this.runner);
66
-
67
- return this;
68
- }
69
-
70
- public listen(port = 8080, listener: any) {
71
- this.app.listen(process.env.PORT || port, () => {
72
- if (listener) {
73
- listener();
74
- }
75
-
76
- this.listener(this.app);
77
- });
78
- }
79
-
80
- public listener(app: httpServer) {
81
- this.server.onListening(app);
82
- }
83
-
84
- public async close() {
85
- await this.server.close();
86
- await new Promise<void>(resolve =>
87
- this.app.close(() => {
88
- resolve();
89
- }),
90
- );
91
- }
92
-
93
- private createProdServer() {
94
- const { options } = this;
95
-
96
- if (options.apiOnly) {
97
- return new ModernAPIServer(options);
98
- } else if (options.ssrOnly) {
99
- return new ModernSSRServer(options);
100
- } else if (options.webOnly) {
101
- return new ModernWebServer(options);
102
- } else {
103
- return new ModernServer(options);
104
- }
105
- }
106
-
107
- private createDevServer() {
108
- const { options } = this;
109
- const {
110
- ModernAPIDevServer,
111
- ModernSSRDevServer,
112
- ModernDevServer,
113
- } = require('./dev-server');
114
-
115
- if (options.apiOnly) {
116
- return new ModernAPIDevServer(options);
117
- } else if (options.ssrOnly) {
118
- return new ModernSSRDevServer(options);
119
- } else {
120
- return new ModernDevServer(options);
121
- }
122
- }
123
-
124
- private async createHookRunner() {
125
- const { options } = this;
126
-
127
- options.plugins?.forEach(p => {
128
- serverManager.usePlugin(p);
129
- });
130
-
131
- const appContext = await this.initAppContext();
132
- serverManager.run(() => {
133
- ConfigContext.set(this.options.config as UserConfig);
134
- AppContext.set({
135
- ...appContext,
136
- distDirectory: path.join(
137
- options.pwd,
138
- options.config.output?.path || 'dist',
139
- ),
140
- });
141
- });
142
-
143
- return serverManager.init({});
144
- }
145
-
146
- private async initAppContext() {
147
- const appDirectory = await initAppDir();
148
-
149
- const loaded = await loadUserConfig(appDirectory);
150
-
151
- const plugins = this.options.plugins?.map(p => ({
152
- server: p,
153
- cli: undefined,
154
- }));
155
-
156
- const appContext = initAppContext(
157
- appDirectory,
158
- plugins || [],
159
- loaded.filePath,
160
- );
161
- return appContext;
162
- }
163
- }
@@ -1,97 +0,0 @@
1
- import { APIServerStartInput } from '@modern-js/server-plugin';
2
- import { mergeExtension } from '../utils';
3
- import { ModernRoute, ModernRouteInterface, RouteMatcher } from '../libs/route';
4
- import { ApiServerMode } from '../constants';
5
- import { ModernServerContext } from '../libs/context';
6
- import { ModernServer } from './modern-server';
7
-
8
- export class ModernSSRServer extends ModernServer {
9
- // Todo should not invoke any route hook in modernSSRServer
10
-
11
- protected async warmupSSRBundle() {
12
- // empty
13
- }
14
-
15
- protected verifyMatch(context: ModernServerContext, matched: RouteMatcher) {
16
- if (matched.generate().isApi) {
17
- this.render404(context);
18
- }
19
- }
20
-
21
- protected prepareAPIHandler(
22
- _m: ApiServerMode,
23
- _: APIServerStartInput['config'],
24
- ) {
25
- return null as any;
26
- }
27
-
28
- protected async prepareWebHandler(
29
- extension: ReturnType<typeof mergeExtension>,
30
- ) {
31
- return super.prepareWebHandler(extension);
32
- }
33
-
34
- // protected filterRoutes(routes: ModernRouteInterface[]) {
35
- // return routes.filter(route => route.entryName);
36
- // }
37
-
38
- protected async preServerInit() {
39
- // empty
40
- }
41
- }
42
-
43
- export class ModernAPIServer extends ModernServer {
44
- protected async emitRouteHook(_: string, _input: any) {
45
- // empty
46
- }
47
-
48
- protected async warmupSSRBundle() {
49
- // empty
50
- }
51
-
52
- protected prepareWebHandler(_: ReturnType<typeof mergeExtension>) {
53
- return null as any;
54
- }
55
-
56
- protected async prepareAPIHandler(
57
- mode: ApiServerMode,
58
- extension: APIServerStartInput['config'],
59
- ) {
60
- return super.prepareAPIHandler(mode, extension);
61
- }
62
-
63
- protected filterRoutes(routes: ModernRouteInterface[]) {
64
- return routes.filter(route => route.isApi);
65
- }
66
-
67
- protected async preServerInit() {
68
- // empty
69
- }
70
- }
71
-
72
- export class ModernWebServer extends ModernServer {
73
- protected async warmupSSRBundle() {
74
- // empty
75
- }
76
-
77
- protected async handleAPI(context: ModernServerContext) {
78
- const { proxyTarget } = this;
79
- if (!proxyTarget?.api) {
80
- this.proxy();
81
- } else {
82
- this.render404(context);
83
- }
84
- }
85
-
86
- protected async handleWeb(context: ModernServerContext, route: ModernRoute) {
87
- const { proxyTarget } = this;
88
-
89
- if (route.isSSR && proxyTarget?.ssr) {
90
- return this.proxy();
91
- } else {
92
- // if no proxyTarget but access web server, degradation to csr
93
- route.isSSR = false;
94
- return super.handleWeb(context, route);
95
- }
96
- }
97
- }