@modern-js/server 2.69.5 → 3.0.0-alpha.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/cjs/createDevServer.js +98 -100
- package/dist/cjs/dev-tools/https/index.js +57 -49
- package/dist/cjs/dev-tools/watcher/dependencyTree.js +94 -92
- package/dist/cjs/dev-tools/watcher/index.js +129 -124
- package/dist/cjs/dev-tools/watcher/statsCache.js +84 -81
- package/dist/cjs/dev.js +104 -110
- package/dist/cjs/helpers/devOptions.js +55 -54
- package/dist/cjs/helpers/fileReader.js +48 -44
- package/dist/cjs/helpers/index.js +168 -107
- package/dist/cjs/helpers/mock.js +121 -124
- package/dist/cjs/helpers/repack.js +45 -39
- package/dist/cjs/helpers/utils.js +34 -26
- package/dist/cjs/index.js +33 -25
- package/dist/cjs/types.js +17 -15
- package/dist/esm/createDevServer.mjs +59 -0
- package/dist/esm/dev-tools/https/index.mjs +28 -0
- package/dist/esm/dev-tools/watcher/dependencyTree.mjs +57 -0
- package/dist/esm/dev-tools/watcher/index.mjs +88 -0
- package/dist/esm/dev-tools/watcher/statsCache.mjs +50 -0
- package/dist/esm/dev.mjs +77 -0
- package/dist/esm/helpers/devOptions.mjs +24 -0
- package/dist/esm/helpers/fileReader.mjs +18 -0
- package/dist/esm/helpers/index.mjs +65 -0
- package/dist/esm/helpers/mock.mjs +87 -0
- package/dist/esm/helpers/repack.mjs +16 -0
- package/dist/esm/helpers/utils.mjs +3 -0
- package/dist/{esm-node/index.js → esm/index.mjs} +1 -3
- package/dist/esm-node/createDevServer.mjs +59 -0
- package/dist/esm-node/dev-tools/https/index.mjs +28 -0
- package/dist/esm-node/dev-tools/watcher/dependencyTree.mjs +57 -0
- package/dist/esm-node/dev-tools/watcher/index.mjs +88 -0
- package/dist/esm-node/dev-tools/watcher/statsCache.mjs +50 -0
- package/dist/esm-node/dev.mjs +77 -0
- package/dist/esm-node/helpers/devOptions.mjs +24 -0
- package/dist/esm-node/helpers/fileReader.mjs +18 -0
- package/dist/esm-node/helpers/index.mjs +65 -0
- package/dist/esm-node/helpers/mock.mjs +87 -0
- package/dist/esm-node/helpers/repack.mjs +16 -0
- package/dist/esm-node/helpers/utils.mjs +3 -0
- package/dist/esm-node/index.mjs +2 -0
- package/dist/types/createDevServer.d.ts +1 -1
- package/dist/types/dev.d.ts +4 -4
- package/dist/types/helpers/devOptions.d.ts +10 -6
- package/dist/types/helpers/fileReader.d.ts +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/types.d.ts +48 -12
- package/package.json +42 -31
- package/rslib.config.mts +4 -0
- package/dist/cjs/helpers/constants.js +0 -49
- package/dist/esm/createDevServer.js +0 -154
- package/dist/esm/dev-tools/https/index.js +0 -74
- package/dist/esm/dev-tools/watcher/dependencyTree.js +0 -88
- package/dist/esm/dev-tools/watcher/index.js +0 -120
- package/dist/esm/dev-tools/watcher/statsCache.js +0 -80
- package/dist/esm/dev.js +0 -126
- package/dist/esm/helpers/constants.js +0 -25
- package/dist/esm/helpers/devOptions.js +0 -35
- package/dist/esm/helpers/fileReader.js +0 -43
- package/dist/esm/helpers/index.js +0 -123
- package/dist/esm/helpers/mock.js +0 -266
- package/dist/esm/helpers/repack.js +0 -20
- package/dist/esm/helpers/utils.js +0 -5
- package/dist/esm/index.js +0 -4
- package/dist/esm-node/createDevServer.js +0 -71
- package/dist/esm-node/dev-tools/https/index.js +0 -30
- package/dist/esm-node/dev-tools/watcher/dependencyTree.js +0 -67
- package/dist/esm-node/dev-tools/watcher/index.js +0 -100
- package/dist/esm-node/dev-tools/watcher/statsCache.js +0 -58
- package/dist/esm-node/dev.js +0 -93
- package/dist/esm-node/helpers/constants.js +0 -25
- package/dist/esm-node/helpers/devOptions.js +0 -35
- package/dist/esm-node/helpers/fileReader.js +0 -24
- package/dist/esm-node/helpers/index.js +0 -73
- package/dist/esm-node/helpers/mock.js +0 -104
- package/dist/esm-node/helpers/repack.js +0 -20
- package/dist/esm-node/helpers/utils.js +0 -5
- package/dist/types/helpers/constants.d.ts +0 -2
- /package/dist/esm/{types.js → types.mjs} +0 -0
- /package/dist/esm-node/{types.js → types.mjs} +0 -0
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
debug: ()=>debug
|
|
22
28
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const utils_namespaceObject = require("@modern-js/utils");
|
|
30
|
+
const debug = (0, utils_namespaceObject.createDebugger)('server');
|
|
31
|
+
exports.debug = __webpack_exports__.debug;
|
|
32
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
33
|
+
"debug"
|
|
34
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
35
|
+
Object.defineProperty(exports, '__esModule', {
|
|
36
|
+
value: true
|
|
29
37
|
});
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
createDevServer: ()=>external_createDevServer_js_namespaceObject.createDevServer
|
|
22
28
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
const external_createDevServer_js_namespaceObject = require("./createDevServer.js");
|
|
30
|
+
exports.createDevServer = __webpack_exports__.createDevServer;
|
|
31
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
32
|
+
"createDevServer"
|
|
33
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
34
|
+
Object.defineProperty(exports, '__esModule', {
|
|
35
|
+
value: true
|
|
28
36
|
});
|
package/dist/cjs/types.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
var
|
|
16
|
-
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import node_path from "node:path";
|
|
2
|
+
import { createServerBase } from "@modern-js/server-core";
|
|
3
|
+
import { createNodeServer, loadServerRuntimeConfig } from "@modern-js/server-core/node";
|
|
4
|
+
import { devPlugin } from "./dev";
|
|
5
|
+
import { getDevAssetPrefix, getDevOptions } from "./helpers";
|
|
6
|
+
async function createDevServer(options, applyPlugins) {
|
|
7
|
+
const { config, pwd, serverConfigPath, builder } = options;
|
|
8
|
+
const dev = getDevOptions(options.dev);
|
|
9
|
+
const distDir = node_path.resolve(pwd, config.output.distPath?.root || 'dist');
|
|
10
|
+
const serverConfig = await loadServerRuntimeConfig(serverConfigPath) || {};
|
|
11
|
+
const prodServerOptions = {
|
|
12
|
+
...options,
|
|
13
|
+
pwd: distDir,
|
|
14
|
+
serverConfig: {
|
|
15
|
+
...serverConfig,
|
|
16
|
+
...options.serverConfig
|
|
17
|
+
},
|
|
18
|
+
plugins: [
|
|
19
|
+
...serverConfig.plugins || [],
|
|
20
|
+
...options.plugins || []
|
|
21
|
+
]
|
|
22
|
+
};
|
|
23
|
+
const server = createServerBase(prodServerOptions);
|
|
24
|
+
const devHttpsOption = 'object' == typeof dev && dev.https;
|
|
25
|
+
const isHttp2 = !!devHttpsOption;
|
|
26
|
+
let nodeServer;
|
|
27
|
+
if (devHttpsOption) {
|
|
28
|
+
const { genHttpsOptions } = await import("./dev-tools/https");
|
|
29
|
+
const httpsOptions = await genHttpsOptions(devHttpsOption, pwd);
|
|
30
|
+
nodeServer = await createNodeServer(server.handle.bind(server), httpsOptions, isHttp2);
|
|
31
|
+
} else nodeServer = await createNodeServer(server.handle.bind(server));
|
|
32
|
+
const promise = getDevAssetPrefix(builder);
|
|
33
|
+
let compiler = null;
|
|
34
|
+
builder?.onAfterCreateCompiler((context)=>{
|
|
35
|
+
compiler = context.compiler;
|
|
36
|
+
});
|
|
37
|
+
const builderDevServer = await builder?.createDevServer({
|
|
38
|
+
runCompile: options.runCompile,
|
|
39
|
+
compiler: options.compiler
|
|
40
|
+
});
|
|
41
|
+
server.addPlugins([
|
|
42
|
+
devPlugin({
|
|
43
|
+
...options,
|
|
44
|
+
builderDevServer
|
|
45
|
+
}, compiler)
|
|
46
|
+
]);
|
|
47
|
+
const assetPrefix = await promise;
|
|
48
|
+
if (assetPrefix) prodServerOptions.config.output.assetPrefix = assetPrefix;
|
|
49
|
+
await applyPlugins(server, prodServerOptions, nodeServer);
|
|
50
|
+
await server.init();
|
|
51
|
+
const afterListen = async ()=>{
|
|
52
|
+
await builderDevServer?.afterListen();
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
server: nodeServer,
|
|
56
|
+
afterListen
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export { createDevServer };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { chalk, getPackageManager, logger } from "@modern-js/utils";
|
|
2
|
+
const genHttpsOptions = async (userOptions, pwd)=>{
|
|
3
|
+
const httpsOptions = 'boolean' == typeof userOptions ? {} : userOptions;
|
|
4
|
+
if (!httpsOptions.key || !httpsOptions.cert) {
|
|
5
|
+
let devcertPath;
|
|
6
|
+
try {
|
|
7
|
+
devcertPath = require.resolve('devcert', {
|
|
8
|
+
paths: [
|
|
9
|
+
pwd,
|
|
10
|
+
__dirname
|
|
11
|
+
]
|
|
12
|
+
});
|
|
13
|
+
} catch (err) {
|
|
14
|
+
const packageManager = await getPackageManager(pwd);
|
|
15
|
+
const command = chalk.yellow.bold(`${packageManager} add devcert@1.2.2 -D`);
|
|
16
|
+
logger.error('You have enabled "dev.https" option, but the "devcert" package is not installed.');
|
|
17
|
+
logger.error(`Please run ${command} to install manually, otherwise the https can not work.`);
|
|
18
|
+
throw new Error('[https] "devcert" is not found.');
|
|
19
|
+
}
|
|
20
|
+
const devcert = require(devcertPath);
|
|
21
|
+
const selfsign = await devcert.certificateFor([
|
|
22
|
+
'localhost'
|
|
23
|
+
]);
|
|
24
|
+
return selfsign;
|
|
25
|
+
}
|
|
26
|
+
return httpsOptions;
|
|
27
|
+
};
|
|
28
|
+
export { genHttpsOptions };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import minimatch from "minimatch";
|
|
2
|
+
const defaultIgnores = [
|
|
3
|
+
'**/coverage/**',
|
|
4
|
+
'**/node_modules/**',
|
|
5
|
+
'**/.*/**',
|
|
6
|
+
'**/*.d.ts',
|
|
7
|
+
'**/*.log'
|
|
8
|
+
];
|
|
9
|
+
class DependencyTree {
|
|
10
|
+
getNode(path) {
|
|
11
|
+
return this.tree.get(path);
|
|
12
|
+
}
|
|
13
|
+
update(cache) {
|
|
14
|
+
this.tree.clear();
|
|
15
|
+
Object.keys(cache).forEach((path)=>{
|
|
16
|
+
if (!this.shouldIgnore(path)) {
|
|
17
|
+
const module = cache[path];
|
|
18
|
+
this.tree.set(module.filename, {
|
|
19
|
+
module,
|
|
20
|
+
parent: new Set(),
|
|
21
|
+
children: new Set()
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
for (const treeNode of this.tree.values()){
|
|
26
|
+
const { parent } = treeNode.module;
|
|
27
|
+
const { children } = treeNode.module;
|
|
28
|
+
if (parent && !this.shouldIgnore(parent.filename)) {
|
|
29
|
+
const parentTreeNode = this.tree.get(parent.filename);
|
|
30
|
+
if (parentTreeNode) treeNode.parent.add(parentTreeNode);
|
|
31
|
+
}
|
|
32
|
+
children?.forEach((child)=>{
|
|
33
|
+
if (!this.shouldIgnore(child.filename)) {
|
|
34
|
+
const childTreeNode = this.tree.get(child.filename);
|
|
35
|
+
if (childTreeNode) {
|
|
36
|
+
treeNode.children.add(childTreeNode);
|
|
37
|
+
childTreeNode.parent.add(treeNode);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
shouldIgnore(path) {
|
|
44
|
+
return !path || Boolean(this.ignore.find((rule)=>minimatch.match([
|
|
45
|
+
path
|
|
46
|
+
], rule, {
|
|
47
|
+
dot: true
|
|
48
|
+
}).length > 0));
|
|
49
|
+
}
|
|
50
|
+
constructor(){
|
|
51
|
+
this.tree = new Map();
|
|
52
|
+
this.ignore = [
|
|
53
|
+
...defaultIgnores
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export { DependencyTree, defaultIgnores };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { chokidar, fs } from "@modern-js/utils";
|
|
3
|
+
import { DependencyTree } from "./dependencyTree";
|
|
4
|
+
import { StatsCache } from "./statsCache";
|
|
5
|
+
const defaultWatchOptions = {
|
|
6
|
+
ignoreInitial: true,
|
|
7
|
+
ignored: /api\/typings\/.*/
|
|
8
|
+
};
|
|
9
|
+
const getWatchedFiles = (watcher)=>{
|
|
10
|
+
const watched = watcher.getWatched();
|
|
11
|
+
const files = [];
|
|
12
|
+
Object.keys(watched).forEach((dir)=>{
|
|
13
|
+
watched[dir].forEach((fileName)=>{
|
|
14
|
+
files.push(path.join(dir, fileName));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
return files;
|
|
18
|
+
};
|
|
19
|
+
const mergeWatchOptions = (options)=>{
|
|
20
|
+
const watchOptions = {
|
|
21
|
+
...options
|
|
22
|
+
};
|
|
23
|
+
if (watchOptions) {
|
|
24
|
+
const { ignored } = watchOptions;
|
|
25
|
+
const finalIgnored = ignored ? [
|
|
26
|
+
defaultWatchOptions.ignored,
|
|
27
|
+
...Array.isArray(ignored) ? ignored : [
|
|
28
|
+
ignored
|
|
29
|
+
]
|
|
30
|
+
] : ignored;
|
|
31
|
+
if (finalIgnored) watchOptions.ignored = finalIgnored;
|
|
32
|
+
}
|
|
33
|
+
const finalWatchOptions = {
|
|
34
|
+
...defaultWatchOptions,
|
|
35
|
+
...watchOptions
|
|
36
|
+
};
|
|
37
|
+
return finalWatchOptions;
|
|
38
|
+
};
|
|
39
|
+
class Watcher {
|
|
40
|
+
listen(files, options, callback) {
|
|
41
|
+
const watched = files.filter(Boolean);
|
|
42
|
+
const filenames = watched.map((filename)=>filename.replace(/\\/g, '/'));
|
|
43
|
+
const cache = new StatsCache();
|
|
44
|
+
const watcher = chokidar.watch(filenames, options);
|
|
45
|
+
watcher.on('ready', ()=>{
|
|
46
|
+
cache.add(getWatchedFiles(watcher));
|
|
47
|
+
});
|
|
48
|
+
watcher.on('change', (changed)=>{
|
|
49
|
+
if (!fs.existsSync(changed) || cache.isDiff(changed)) {
|
|
50
|
+
cache.refresh(changed);
|
|
51
|
+
callback(changed, 'change');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
watcher.on('add', (changed)=>{
|
|
55
|
+
if (!cache.has(changed)) {
|
|
56
|
+
cache.add([
|
|
57
|
+
changed
|
|
58
|
+
]);
|
|
59
|
+
callback(changed, 'add');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
watcher.on('unlink', (changed)=>{
|
|
63
|
+
cache.del(changed);
|
|
64
|
+
callback(changed, 'unlink');
|
|
65
|
+
});
|
|
66
|
+
this.watcher = watcher;
|
|
67
|
+
}
|
|
68
|
+
createDepTree() {
|
|
69
|
+
this.dependencyTree = new DependencyTree();
|
|
70
|
+
}
|
|
71
|
+
updateDepTree() {
|
|
72
|
+
this.dependencyTree?.update(require.cache);
|
|
73
|
+
}
|
|
74
|
+
cleanDepCache(filepath) {
|
|
75
|
+
const node = this.dependencyTree?.getNode(filepath);
|
|
76
|
+
if (node && require.cache[filepath]) {
|
|
77
|
+
delete require.cache[filepath];
|
|
78
|
+
for (const parentNode of node.parent.values())this.cleanDepCache(parentNode.module.filename);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
close() {
|
|
82
|
+
return this.watcher.close();
|
|
83
|
+
}
|
|
84
|
+
constructor(){
|
|
85
|
+
this.dependencyTree = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export { Watcher as default, defaultWatchOptions, getWatchedFiles, mergeWatchOptions };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import crypto_0 from "crypto";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
class StatsCache {
|
|
4
|
+
add(files) {
|
|
5
|
+
const { cachedHash, cachedSize } = this;
|
|
6
|
+
for (const filename of files)if (fs.existsSync(filename)) {
|
|
7
|
+
const stats = fs.statSync(filename);
|
|
8
|
+
if (stats.isFile() && !cachedHash[filename]) {
|
|
9
|
+
cachedHash[filename] = this.hash(stats, filename);
|
|
10
|
+
cachedSize[filename] = stats.size;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
refresh(filename) {
|
|
15
|
+
const { cachedHash, cachedSize } = this;
|
|
16
|
+
if (fs.existsSync(filename)) {
|
|
17
|
+
const stats = fs.statSync(filename);
|
|
18
|
+
if (stats.isFile()) {
|
|
19
|
+
cachedHash[filename] = this.hash(stats, filename);
|
|
20
|
+
cachedSize[filename] = stats.size;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
del(filename) {
|
|
25
|
+
if (this.cachedHash[filename]) {
|
|
26
|
+
delete this.cachedHash[filename];
|
|
27
|
+
delete this.cachedSize[filename];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
isDiff(filename) {
|
|
31
|
+
const { cachedHash, cachedSize } = this;
|
|
32
|
+
const stats = fs.statSync(filename);
|
|
33
|
+
const hash = cachedHash[filename];
|
|
34
|
+
const size = cachedSize[filename];
|
|
35
|
+
if (stats.size !== size) return true;
|
|
36
|
+
if (this.hash(stats, filename) !== hash) return true;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
has(filename) {
|
|
40
|
+
return Boolean(this.cachedHash[filename]);
|
|
41
|
+
}
|
|
42
|
+
hash(stats, filename) {
|
|
43
|
+
return crypto_0.createHash('md5').update(fs.readFileSync(filename)).digest('hex');
|
|
44
|
+
}
|
|
45
|
+
constructor(){
|
|
46
|
+
this.cachedHash = {};
|
|
47
|
+
this.cachedSize = {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export { StatsCache };
|
package/dist/esm/dev.mjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { connectMid2HonoMid } from "@modern-js/server-core/node";
|
|
2
|
+
import { API_DIR, SHARED_DIR } from "@modern-js/utils";
|
|
3
|
+
import { getDevOptions, getMockMiddleware, initFileReader, onRepack, startWatcher } from "./helpers";
|
|
4
|
+
const devPlugin = (options, compiler)=>({
|
|
5
|
+
name: '@modern-js/plugin-dev',
|
|
6
|
+
setup (api) {
|
|
7
|
+
const { config, pwd, builder, builderDevServer } = options;
|
|
8
|
+
const closeCb = [];
|
|
9
|
+
const dev = getDevOptions(options.dev);
|
|
10
|
+
api.onPrepare(async ()=>{
|
|
11
|
+
const { middlewares: builderMiddlewares, close, connectWebSocket } = builderDevServer || {};
|
|
12
|
+
close && closeCb.push(close);
|
|
13
|
+
const { middlewares, distDirectory, nodeServer, apiDirectory, sharedDirectory, serverBase } = api.getServerContext();
|
|
14
|
+
connectWebSocket && nodeServer && connectWebSocket({
|
|
15
|
+
server: nodeServer
|
|
16
|
+
});
|
|
17
|
+
const hooks = api.getHooks();
|
|
18
|
+
builder?.onDevCompileDone(({ stats })=>{
|
|
19
|
+
if ('server' !== stats.toJson({
|
|
20
|
+
all: false
|
|
21
|
+
}).name) onRepack(distDirectory, hooks);
|
|
22
|
+
});
|
|
23
|
+
const { watchOptions } = config.server;
|
|
24
|
+
const watcher = startWatcher({
|
|
25
|
+
pwd,
|
|
26
|
+
distDir: distDirectory,
|
|
27
|
+
apiDir: apiDirectory || API_DIR,
|
|
28
|
+
sharedDir: sharedDirectory || SHARED_DIR,
|
|
29
|
+
watchOptions,
|
|
30
|
+
server: serverBase
|
|
31
|
+
});
|
|
32
|
+
closeCb.push(watcher.close.bind(watcher));
|
|
33
|
+
closeCb.length > 0 && nodeServer?.on('close', ()=>{
|
|
34
|
+
closeCb.forEach((cb)=>{
|
|
35
|
+
cb();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
const before = [];
|
|
39
|
+
const after = [];
|
|
40
|
+
const { setupMiddlewares = [] } = dev;
|
|
41
|
+
setupMiddlewares.forEach((handler)=>{
|
|
42
|
+
handler({
|
|
43
|
+
unshift: (...handlers)=>before.unshift(...handlers),
|
|
44
|
+
push: (...handlers)=>after.push(...handlers)
|
|
45
|
+
}, {
|
|
46
|
+
sockWrite: ()=>{}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
before.forEach((middleware, index)=>{
|
|
50
|
+
middlewares.push({
|
|
51
|
+
name: `before-dev-server-${index}`,
|
|
52
|
+
handler: connectMid2HonoMid(middleware)
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
const mockMiddleware = await getMockMiddleware(pwd);
|
|
56
|
+
middlewares.push({
|
|
57
|
+
name: 'mock-dev',
|
|
58
|
+
handler: mockMiddleware
|
|
59
|
+
});
|
|
60
|
+
builderMiddlewares && middlewares.push({
|
|
61
|
+
name: 'rsbuild-dev',
|
|
62
|
+
handler: connectMid2HonoMid(builderMiddlewares)
|
|
63
|
+
});
|
|
64
|
+
after.forEach((middleware, index)=>{
|
|
65
|
+
middlewares.push({
|
|
66
|
+
name: `after-dev-server-${index}`,
|
|
67
|
+
handler: connectMid2HonoMid(middleware)
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
middlewares.push({
|
|
71
|
+
name: 'init-file-reader',
|
|
72
|
+
handler: initFileReader(compiler)
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
export { devPlugin };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const getDevOptions = (devOptions)=>{
|
|
2
|
+
const defaultOptions = {
|
|
3
|
+
https: false,
|
|
4
|
+
server: {}
|
|
5
|
+
};
|
|
6
|
+
return {
|
|
7
|
+
...defaultOptions,
|
|
8
|
+
...devOptions
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
const getDevAssetPrefix = (builder)=>new Promise((resolve)=>{
|
|
12
|
+
if (!builder) return resolve('');
|
|
13
|
+
builder?.onAfterCreateCompiler((params)=>{
|
|
14
|
+
let webCompiler;
|
|
15
|
+
webCompiler = 'compilers' in params.compiler ? params.compiler.compilers.find((c)=>'web' === c.name || 'client' === c.name) : params.compiler;
|
|
16
|
+
const publicPath = webCompiler?.options?.output?.publicPath;
|
|
17
|
+
if (publicPath && 'string' == typeof publicPath) {
|
|
18
|
+
const formatPublicPath = publicPath.replace(/^https?:\/\/[^/]+/, '');
|
|
19
|
+
return resolve(formatPublicPath);
|
|
20
|
+
}
|
|
21
|
+
return resolve('');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
export { getDevAssetPrefix, getDevOptions };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { fileReader } from "@modern-js/runtime-utils/fileReader";
|
|
2
|
+
const initFileReader = (compiler)=>{
|
|
3
|
+
let isInit = false;
|
|
4
|
+
return async (ctx, next)=>{
|
|
5
|
+
if (isInit) return next();
|
|
6
|
+
isInit = true;
|
|
7
|
+
const { res } = ctx.env.node;
|
|
8
|
+
if (!compiler) {
|
|
9
|
+
fileReader.reset();
|
|
10
|
+
return next();
|
|
11
|
+
}
|
|
12
|
+
const { outputFileSystem } = 'compilers' in compiler ? compiler.compilers[0] : compiler;
|
|
13
|
+
if (outputFileSystem) fileReader.reset(outputFileSystem);
|
|
14
|
+
else fileReader.reset();
|
|
15
|
+
return next();
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export { initFileReader };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { AGGRED_DIR } from "@modern-js/server-core";
|
|
3
|
+
import { SERVER_BUNDLE_DIRECTORY, SERVER_DIR, logger } from "@modern-js/utils";
|
|
4
|
+
import dev_tools_watcher, { mergeWatchOptions } from "../dev-tools/watcher";
|
|
5
|
+
import { initOrUpdateMockMiddlewares } from "./mock";
|
|
6
|
+
import { debug } from "./utils";
|
|
7
|
+
export * from "./repack";
|
|
8
|
+
export * from "./devOptions";
|
|
9
|
+
export * from "./fileReader";
|
|
10
|
+
export * from "./mock";
|
|
11
|
+
async function onServerChange({ pwd, filepath, event, server }) {
|
|
12
|
+
const { mock } = AGGRED_DIR;
|
|
13
|
+
const mockPath = path.normalize(path.join(pwd, mock));
|
|
14
|
+
const { hooks } = server;
|
|
15
|
+
if (filepath.startsWith(mockPath)) {
|
|
16
|
+
await initOrUpdateMockMiddlewares(pwd);
|
|
17
|
+
logger.info('Finish update the mock handlers');
|
|
18
|
+
} else try {
|
|
19
|
+
const fileChangeEvent = {
|
|
20
|
+
type: 'file-change',
|
|
21
|
+
payload: [
|
|
22
|
+
{
|
|
23
|
+
filename: filepath,
|
|
24
|
+
event
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
await hooks.onReset.call({
|
|
29
|
+
event: fileChangeEvent
|
|
30
|
+
});
|
|
31
|
+
debug(`Finish reload server, trigger by ${filepath} ${event}`);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
logger.error(e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function startWatcher({ pwd, distDir, apiDir, sharedDir, watchOptions, server }) {
|
|
37
|
+
const { mock } = AGGRED_DIR;
|
|
38
|
+
const defaultWatched = [
|
|
39
|
+
`${mock}/**/*`,
|
|
40
|
+
`${SERVER_DIR}/**/*`,
|
|
41
|
+
`${apiDir}/**`,
|
|
42
|
+
`${sharedDir}/**/*`,
|
|
43
|
+
`${distDir}/${SERVER_BUNDLE_DIRECTORY}/*-server-loaders.js`
|
|
44
|
+
];
|
|
45
|
+
const mergedWatchOptions = mergeWatchOptions(watchOptions);
|
|
46
|
+
const defaultWatchedPaths = defaultWatched.map((p)=>{
|
|
47
|
+
const finalPath = path.isAbsolute(p) ? p : path.join(pwd, p);
|
|
48
|
+
return path.normalize(finalPath);
|
|
49
|
+
});
|
|
50
|
+
const watcher = new dev_tools_watcher();
|
|
51
|
+
watcher.createDepTree();
|
|
52
|
+
watcher.listen(defaultWatchedPaths, mergedWatchOptions, (filepath, event)=>{
|
|
53
|
+
if (filepath.includes('-server-loaders.js')) return void delete require.cache[filepath];
|
|
54
|
+
watcher.updateDepTree();
|
|
55
|
+
watcher.cleanDepCache(filepath);
|
|
56
|
+
onServerChange({
|
|
57
|
+
pwd,
|
|
58
|
+
filepath,
|
|
59
|
+
event,
|
|
60
|
+
server
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
return watcher;
|
|
64
|
+
}
|
|
65
|
+
export { startWatcher };
|