@modern-js/server 1.3.0 → 1.3.1-beta.0
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.
- package/dist/js/modern/dev-tools/watcher/index.js +5 -5
- package/dist/js/modern/server/dev-server/dev-server.js +15 -5
- package/dist/js/node/dev-tools/watcher/index.js +5 -5
- package/dist/js/node/server/dev-server/dev-server.js +17 -5
- package/dist/types/dev-tools/watcher/index.d.ts +2 -1
- package/jest.config.js +1 -0
- package/package.json +1 -1
- package/src/dev-tools/watcher/index.ts +10 -6
- package/src/server/dev-server/dev-server.ts +38 -22
- package/tests/server.test.ts +19 -0
- package/tests/watcher.test.ts +96 -0
|
@@ -19,13 +19,13 @@ export default class Watcher {
|
|
|
19
19
|
this.watcher = void 0;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
listen(files, callback) {
|
|
22
|
+
listen(files, options, callback) {
|
|
23
23
|
const watched = files.filter(Boolean);
|
|
24
|
+
const filenames = watched.map(filename => filename.replace(/\\/g, '/')); // eslint-disable-next-line no-console
|
|
25
|
+
|
|
26
|
+
console.log('watched files:', filenames);
|
|
24
27
|
const cache = new StatsCache();
|
|
25
|
-
const watcher = chokidar.watch(
|
|
26
|
-
// 初始化的时候不触发 add、addDir 事件
|
|
27
|
-
ignoreInitial: true
|
|
28
|
-
});
|
|
28
|
+
const watcher = chokidar.watch(filenames, options);
|
|
29
29
|
watcher.on('ready', () => {
|
|
30
30
|
cache.add(getWatchedFiles(watcher));
|
|
31
31
|
});
|
|
@@ -121,9 +121,13 @@ export class ModernDevServer extends ModernServer {
|
|
|
121
121
|
super.close();
|
|
122
122
|
await this.watcher.close();
|
|
123
123
|
await new Promise(resolve => {
|
|
124
|
-
this.devMiddleware
|
|
124
|
+
if (this.devMiddleware) {
|
|
125
|
+
this.devMiddleware.close(() => {
|
|
126
|
+
resolve();
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
125
129
|
resolve();
|
|
126
|
-
}
|
|
130
|
+
}
|
|
127
131
|
});
|
|
128
132
|
}
|
|
129
133
|
|
|
@@ -239,16 +243,22 @@ export class ModernDevServer extends ModernServer {
|
|
|
239
243
|
const {
|
|
240
244
|
mock
|
|
241
245
|
} = AGGRED_DIR;
|
|
242
|
-
const defaultWatched = [`${
|
|
246
|
+
const defaultWatched = [`${mock}/**/*`, `${SERVER_DIR}/**/*`, `${API_DIR}/**`, `${SHARED_DIR}/**/*`];
|
|
247
|
+
const defaultWatchedPaths = defaultWatched.map(p => path.normalize(path.join(pwd, p)));
|
|
248
|
+
const mockPath = path.normalize(path.join(pwd, mock));
|
|
243
249
|
const watcher = new Watcher();
|
|
244
250
|
watcher.createDepTree(); // 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
|
|
245
251
|
|
|
246
|
-
watcher.listen(
|
|
252
|
+
watcher.listen(defaultWatchedPaths, {
|
|
253
|
+
// 初始化的时候不触发 add、addDir 事件
|
|
254
|
+
ignoreInitial: true,
|
|
255
|
+
ignored: /api\/typings\/.*/
|
|
256
|
+
}, filepath => {
|
|
247
257
|
watcher.updateDepTree();
|
|
248
258
|
watcher.cleanDepCache(filepath);
|
|
249
259
|
this.runner.reset();
|
|
250
260
|
|
|
251
|
-
if (filepath.startsWith(
|
|
261
|
+
if (filepath.startsWith(mockPath)) {
|
|
252
262
|
this.mockHandler = createMockHandler({
|
|
253
263
|
pwd
|
|
254
264
|
});
|
|
@@ -30,14 +30,14 @@ class Watcher {
|
|
|
30
30
|
this.watcher = void 0;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
listen(files, callback) {
|
|
33
|
+
listen(files, options, callback) {
|
|
34
34
|
const watched = files.filter(Boolean);
|
|
35
|
+
const filenames = watched.map(filename => filename.replace(/\\/g, '/')); // eslint-disable-next-line no-console
|
|
36
|
+
|
|
37
|
+
console.log('watched files:', filenames);
|
|
35
38
|
const cache = new _statsCache.StatsCache();
|
|
36
39
|
|
|
37
|
-
const watcher = _chokidar.default.watch(
|
|
38
|
-
// 初始化的时候不触发 add、addDir 事件
|
|
39
|
-
ignoreInitial: true
|
|
40
|
-
});
|
|
40
|
+
const watcher = _chokidar.default.watch(filenames, options);
|
|
41
41
|
|
|
42
42
|
watcher.on('ready', () => {
|
|
43
43
|
cache.add(getWatchedFiles(watcher));
|
|
@@ -150,9 +150,13 @@ class ModernDevServer extends _modernServer.ModernServer {
|
|
|
150
150
|
super.close();
|
|
151
151
|
await this.watcher.close();
|
|
152
152
|
await new Promise(resolve => {
|
|
153
|
-
this.devMiddleware
|
|
153
|
+
if (this.devMiddleware) {
|
|
154
|
+
this.devMiddleware.close(() => {
|
|
155
|
+
resolve();
|
|
156
|
+
});
|
|
157
|
+
} else {
|
|
154
158
|
resolve();
|
|
155
|
-
}
|
|
159
|
+
}
|
|
156
160
|
});
|
|
157
161
|
}
|
|
158
162
|
|
|
@@ -268,16 +272,24 @@ class ModernDevServer extends _modernServer.ModernServer {
|
|
|
268
272
|
const {
|
|
269
273
|
mock
|
|
270
274
|
} = _constants.AGGRED_DIR;
|
|
271
|
-
const defaultWatched = [`${
|
|
275
|
+
const defaultWatched = [`${mock}/**/*`, `${_utils.SERVER_DIR}/**/*`, `${_utils.API_DIR}/**`, `${_utils.SHARED_DIR}/**/*`];
|
|
276
|
+
const defaultWatchedPaths = defaultWatched.map(p => _path.default.normalize(_path.default.join(pwd, p)));
|
|
277
|
+
|
|
278
|
+
const mockPath = _path.default.normalize(_path.default.join(pwd, mock));
|
|
279
|
+
|
|
272
280
|
const watcher = new _watcher.default();
|
|
273
281
|
watcher.createDepTree(); // 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
|
|
274
282
|
|
|
275
|
-
watcher.listen(
|
|
283
|
+
watcher.listen(defaultWatchedPaths, {
|
|
284
|
+
// 初始化的时候不触发 add、addDir 事件
|
|
285
|
+
ignoreInitial: true,
|
|
286
|
+
ignored: /api\/typings\/.*/
|
|
287
|
+
}, filepath => {
|
|
276
288
|
watcher.updateDepTree();
|
|
277
289
|
watcher.cleanDepCache(filepath);
|
|
278
290
|
this.runner.reset();
|
|
279
291
|
|
|
280
|
-
if (filepath.startsWith(
|
|
292
|
+
if (filepath.startsWith(mockPath)) {
|
|
281
293
|
this.mockHandler = (0, _mock.createMockHandler)({
|
|
282
294
|
pwd
|
|
283
295
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { WatchOptions } from 'chokidar';
|
|
1
2
|
export default class Watcher {
|
|
2
3
|
private dependencyTree;
|
|
3
4
|
private watcher;
|
|
4
|
-
listen(files: string[], callback: (changed: string) => void): void;
|
|
5
|
+
listen(files: string[], options: WatchOptions, callback: (changed: string) => void): void;
|
|
5
6
|
createDepTree(): void;
|
|
6
7
|
updateDepTree(): void;
|
|
7
8
|
cleanDepCache(filepath: string): void;
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import chokidar, { FSWatcher } from 'chokidar';
|
|
1
|
+
import chokidar, { FSWatcher, WatchOptions } from 'chokidar';
|
|
2
2
|
import { DependencyTree } from './dependency-tree';
|
|
3
3
|
import { StatsCache } from './stats-cache';
|
|
4
4
|
|
|
@@ -18,14 +18,18 @@ export default class Watcher {
|
|
|
18
18
|
|
|
19
19
|
private watcher!: FSWatcher;
|
|
20
20
|
|
|
21
|
-
public listen(
|
|
21
|
+
public listen(
|
|
22
|
+
files: string[],
|
|
23
|
+
options: WatchOptions,
|
|
24
|
+
callback: (changed: string) => void,
|
|
25
|
+
) {
|
|
22
26
|
const watched = files.filter(Boolean);
|
|
27
|
+
const filenames = watched.map(filename => filename.replace(/\\/g, '/'));
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.log('watched files:', filenames);
|
|
23
30
|
|
|
24
31
|
const cache = new StatsCache();
|
|
25
|
-
const watcher = chokidar.watch(
|
|
26
|
-
// 初始化的时候不触发 add、addDir 事件
|
|
27
|
-
ignoreInitial: true,
|
|
28
|
-
});
|
|
32
|
+
const watcher = chokidar.watch(filenames, options);
|
|
29
33
|
|
|
30
34
|
watcher.on('ready', () => {
|
|
31
35
|
cache.add(getWatchedFiles(watcher));
|
|
@@ -84,7 +84,6 @@ export class ModernDevServer extends ModernServer {
|
|
|
84
84
|
// Complete the preparation of services
|
|
85
85
|
public async init(runner: ServerHookRunner) {
|
|
86
86
|
const { conf, pwd, compiler } = this;
|
|
87
|
-
|
|
88
87
|
// mock handler
|
|
89
88
|
this.mockHandler = createMockHandler({ pwd });
|
|
90
89
|
this.addHandler((ctx: ModernServerContext, next: NextFunction) => {
|
|
@@ -150,9 +149,13 @@ export class ModernDevServer extends ModernServer {
|
|
|
150
149
|
super.close();
|
|
151
150
|
await this.watcher.close();
|
|
152
151
|
await new Promise<void>(resolve => {
|
|
153
|
-
this.devMiddleware
|
|
152
|
+
if (this.devMiddleware) {
|
|
153
|
+
this.devMiddleware.close(() => {
|
|
154
|
+
resolve();
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
154
157
|
resolve();
|
|
155
|
-
}
|
|
158
|
+
}
|
|
156
159
|
});
|
|
157
160
|
}
|
|
158
161
|
|
|
@@ -252,32 +255,45 @@ export class ModernDevServer extends ModernServer {
|
|
|
252
255
|
const { pwd } = this;
|
|
253
256
|
const { mock } = AGGRED_DIR;
|
|
254
257
|
const defaultWatched = [
|
|
255
|
-
`${
|
|
256
|
-
`${
|
|
257
|
-
`${
|
|
258
|
-
`${
|
|
258
|
+
`${mock}/**/*`,
|
|
259
|
+
`${SERVER_DIR}/**/*`,
|
|
260
|
+
`${API_DIR}/**`,
|
|
261
|
+
`${SHARED_DIR}/**/*`,
|
|
259
262
|
];
|
|
260
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
|
+
|
|
261
269
|
const watcher = new Watcher();
|
|
262
270
|
watcher.createDepTree();
|
|
263
271
|
|
|
264
272
|
// 监听文件变动,如果有变动则给 client,也就是 start 启动的插件发消息
|
|
265
|
-
watcher.listen(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
+
}
|
|
278
294
|
}
|
|
279
|
-
}
|
|
280
|
-
|
|
295
|
+
},
|
|
296
|
+
);
|
|
281
297
|
|
|
282
298
|
this.watcher = watcher;
|
|
283
299
|
}
|
package/tests/server.test.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { defaultsConfig, NormalizedConfig } from '@modern-js/core';
|
|
|
3
3
|
import { ModernServerContext, NextFunction } from '@modern-js/types';
|
|
4
4
|
import createServer, { Server } from '../src';
|
|
5
5
|
import { ModernServer } from '../src/server/modern-server';
|
|
6
|
+
import Watcher from '../src/dev-tools/watcher';
|
|
6
7
|
|
|
7
8
|
describe('test server', () => {
|
|
8
9
|
test('should throw error when ', resolve => {
|
|
@@ -99,3 +100,21 @@ describe('test server', () => {
|
|
|
99
100
|
});
|
|
100
101
|
});
|
|
101
102
|
});
|
|
103
|
+
|
|
104
|
+
describe('dev server', () => {
|
|
105
|
+
const pwd = path.join(__dirname, './fixtures/pure');
|
|
106
|
+
let devServer: Server;
|
|
107
|
+
|
|
108
|
+
test('watch', async () => {
|
|
109
|
+
devServer = await createServer({
|
|
110
|
+
config: defaultsConfig as NormalizedConfig,
|
|
111
|
+
pwd,
|
|
112
|
+
dev: true,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
116
|
+
// @ts-expect-error
|
|
117
|
+
expect(devServer.server.watcher).toBeInstanceOf(Watcher);
|
|
118
|
+
await devServer.close();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { fs } from '@modern-js/utils';
|
|
3
|
+
import Watcher from '../src/dev-tools/watcher';
|
|
4
|
+
|
|
5
|
+
jest.useRealTimers();
|
|
6
|
+
|
|
7
|
+
describe('watcher', () => {
|
|
8
|
+
let watcher: Watcher;
|
|
9
|
+
jest.setTimeout(25000);
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
watcher = new Watcher();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('should emit change', done => {
|
|
15
|
+
const pwd = path.join(__dirname, './fixtures/pure');
|
|
16
|
+
const serverDir = path.normalize(path.join(pwd, './tmp-server'));
|
|
17
|
+
|
|
18
|
+
const callback = jest.fn();
|
|
19
|
+
if (fs.pathExistsSync(serverDir)) {
|
|
20
|
+
fs.removeSync(serverDir);
|
|
21
|
+
}
|
|
22
|
+
const writeFiles = () => {
|
|
23
|
+
fs.mkdirSync(serverDir);
|
|
24
|
+
fs.writeFileSync(
|
|
25
|
+
path.normalize(path.join(serverDir, 'index.js')),
|
|
26
|
+
'test',
|
|
27
|
+
'utf8',
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const clear = () => {
|
|
32
|
+
fs.removeSync(serverDir);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
watcher.listen(
|
|
36
|
+
[`${serverDir}/**/*`],
|
|
37
|
+
{
|
|
38
|
+
ignoreInitial: true,
|
|
39
|
+
ignored: /api\/typings\/.*/,
|
|
40
|
+
},
|
|
41
|
+
async () => {
|
|
42
|
+
callback();
|
|
43
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
44
|
+
await watcher.close();
|
|
45
|
+
clear();
|
|
46
|
+
done();
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
setTimeout(writeFiles, 100);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('should not emit change when typings file changed', done => {
|
|
54
|
+
const pwd = path.join(__dirname, './fixtures/pure');
|
|
55
|
+
const apiDir = path.normalize(path.join(pwd, './api'));
|
|
56
|
+
|
|
57
|
+
const callback = jest.fn();
|
|
58
|
+
|
|
59
|
+
if (fs.pathExistsSync(apiDir)) {
|
|
60
|
+
fs.removeSync(apiDir);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const writeFiles = () => {
|
|
64
|
+
fs.mkdirSync(path.normalize(path.join(apiDir, 'typings')), {
|
|
65
|
+
recursive: true,
|
|
66
|
+
});
|
|
67
|
+
fs.writeFileSync(
|
|
68
|
+
path.normalize(path.join(apiDir, 'typings/index.js')),
|
|
69
|
+
'test',
|
|
70
|
+
'utf8',
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const clear = () => {
|
|
75
|
+
fs.removeSync(apiDir);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
watcher.listen(
|
|
79
|
+
[`${apiDir}/**/*`],
|
|
80
|
+
{
|
|
81
|
+
ignoreInitial: true,
|
|
82
|
+
ignored: /api\/typings\/.*/,
|
|
83
|
+
},
|
|
84
|
+
callback,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
setTimeout(async () => {
|
|
88
|
+
expect(callback).toHaveBeenCalledTimes(0);
|
|
89
|
+
await watcher.close();
|
|
90
|
+
clear();
|
|
91
|
+
done();
|
|
92
|
+
}, 1000);
|
|
93
|
+
|
|
94
|
+
setTimeout(writeFiles);
|
|
95
|
+
});
|
|
96
|
+
});
|