@modern-js/server 2.4.1-beta.0 → 2.5.1-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/CHANGELOG.md +23 -4
- package/dist/cjs/constants.js +42 -0
- package/dist/cjs/dev-tools/dev-middleware/hmr-client/createSocketUrl.js +65 -0
- package/dist/cjs/dev-tools/dev-middleware/hmr-client/index.js +155 -0
- package/dist/cjs/dev-tools/dev-middleware/index.js +86 -0
- package/dist/cjs/dev-tools/dev-middleware/socket-server.js +159 -0
- package/dist/cjs/dev-tools/https/index.js +52 -0
- package/dist/cjs/dev-tools/mock/getMockData.js +91 -0
- package/dist/cjs/dev-tools/mock/index.js +79 -0
- package/dist/cjs/dev-tools/register/index.js +125 -0
- package/dist/cjs/dev-tools/watcher/dependency-tree.js +89 -0
- package/dist/cjs/dev-tools/watcher/index.js +126 -0
- package/dist/cjs/dev-tools/watcher/stats-cache.js +87 -0
- package/dist/cjs/index.js +35 -0
- package/dist/cjs/server/dev-server.js +267 -0
- package/dist/cjs/server/index.js +39 -0
- package/dist/cjs/types.js +15 -0
- package/dist/esm/constants.js +21 -0
- package/dist/esm/dev-tools/dev-middleware/hmr-client/createSocketUrl.js +51 -0
- package/dist/esm/dev-tools/dev-middleware/hmr-client/index.js +162 -0
- package/dist/esm/dev-tools/dev-middleware/index.js +322 -0
- package/dist/esm/dev-tools/dev-middleware/socket-server.js +209 -0
- package/dist/esm/dev-tools/https/index.js +193 -0
- package/dist/esm/dev-tools/mock/getMockData.js +318 -0
- package/dist/esm/dev-tools/mock/index.js +207 -0
- package/dist/esm/dev-tools/register/index.js +154 -0
- package/dist/esm/dev-tools/watcher/dependency-tree.js +150 -0
- package/dist/esm/dev-tools/watcher/index.js +200 -0
- package/dist/esm/dev-tools/watcher/stats-cache.js +128 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/server/dev-server.js +800 -0
- package/dist/esm/server/index.js +92 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm-node/constants.js +19 -0
- package/dist/esm-node/dev-tools/dev-middleware/hmr-client/createSocketUrl.js +41 -0
- package/dist/esm-node/dev-tools/dev-middleware/hmr-client/index.js +146 -0
- package/dist/esm-node/dev-tools/dev-middleware/index.js +59 -0
- package/dist/esm-node/dev-tools/dev-middleware/socket-server.js +132 -0
- package/dist/esm-node/dev-tools/https/index.js +29 -0
- package/dist/esm-node/dev-tools/mock/getMockData.js +68 -0
- package/dist/esm-node/dev-tools/mock/index.js +50 -0
- package/dist/esm-node/dev-tools/register/index.js +96 -0
- package/dist/esm-node/dev-tools/watcher/dependency-tree.js +59 -0
- package/dist/esm-node/dev-tools/watcher/index.js +95 -0
- package/dist/esm-node/dev-tools/watcher/stats-cache.js +58 -0
- package/dist/esm-node/index.js +12 -0
- package/dist/esm-node/server/dev-server.js +247 -0
- package/dist/esm-node/server/index.js +16 -0
- package/dist/esm-node/types.js +0 -0
- package/dist/js/modern/dev-tools/dev-middleware/hmr-client/index.js +3 -6
- package/dist/js/node/dev-tools/dev-middleware/hmr-client/index.js +3 -6
- package/dist/js/treeshaking/dev-tools/dev-middleware/hmr-client/index.js +1 -6
- package/dist/js/treeshaking/dev-tools/dev-middleware/index.js +2 -2
- package/dist/js/treeshaking/dev-tools/dev-middleware/socket-server.js +2 -2
- package/dist/js/treeshaking/dev-tools/register/index.js +6 -6
- package/dist/js/treeshaking/dev-tools/watcher/index.js +4 -4
- package/dist/js/treeshaking/dev-tools/watcher/stats-cache.js +3 -3
- package/dist/js/treeshaking/server/dev-server.js +10 -10
- package/dist/types/dev-tools/mock/getMockData.d.ts +1 -1
- package/package.json +15 -16
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { resolveBabelConfig } from "@modern-js/server-utils";
|
|
3
|
+
import { fs, getAliasConfig, createDebugger } from "@modern-js/utils";
|
|
4
|
+
const debug = createDebugger("server");
|
|
5
|
+
const checkDep = (depName, paths) => {
|
|
6
|
+
let packagePath = "";
|
|
7
|
+
try {
|
|
8
|
+
packagePath = require.resolve(depName, {
|
|
9
|
+
paths
|
|
10
|
+
});
|
|
11
|
+
} catch (error) {
|
|
12
|
+
}
|
|
13
|
+
return Boolean(packagePath);
|
|
14
|
+
};
|
|
15
|
+
const enableRegister = (projectRoot, config) => {
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
const registerDirs = ["./api", "./server", "./config/mock", "./shared"];
|
|
18
|
+
const TS_CONFIG_FILENAME = `tsconfig.json`;
|
|
19
|
+
const tsconfigPath = path.resolve(projectRoot, TS_CONFIG_FILENAME);
|
|
20
|
+
const isTsProject = fs.existsSync(tsconfigPath);
|
|
21
|
+
const existTsNode = checkDep("ts-node", [projectRoot]);
|
|
22
|
+
const existTsConfigPaths = checkDep("tsconfig-paths", [projectRoot]);
|
|
23
|
+
if (isTsProject && existTsNode && existTsConfigPaths) {
|
|
24
|
+
debug("use ts-node");
|
|
25
|
+
const distPath = ((_a = config.output.distPath) == null ? void 0 : _a.root) || "dist";
|
|
26
|
+
const tsNode = require("ts-node");
|
|
27
|
+
const tsConfigPaths = require("tsconfig-paths");
|
|
28
|
+
const { alias } = config.source;
|
|
29
|
+
const aliasConfig = getAliasConfig(alias, {
|
|
30
|
+
appDirectory: projectRoot,
|
|
31
|
+
tsconfigPath
|
|
32
|
+
});
|
|
33
|
+
const { paths = {}, absoluteBaseUrl = "./" } = aliasConfig;
|
|
34
|
+
const tsPaths = Object.keys(paths).reduce((o, key) => {
|
|
35
|
+
let tsPath = paths[key];
|
|
36
|
+
if (typeof tsPath === "string" && path.isAbsolute(tsPath)) {
|
|
37
|
+
tsPath = path.relative(absoluteBaseUrl, tsPath);
|
|
38
|
+
}
|
|
39
|
+
if (typeof tsPath === "string") {
|
|
40
|
+
tsPath = [tsPath];
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
...o,
|
|
44
|
+
[`${key}`]: tsPath
|
|
45
|
+
};
|
|
46
|
+
}, {});
|
|
47
|
+
tsConfigPaths.register({
|
|
48
|
+
baseUrl: absoluteBaseUrl || "./",
|
|
49
|
+
paths: tsPaths
|
|
50
|
+
});
|
|
51
|
+
tsNode.register({
|
|
52
|
+
project: tsconfigPath,
|
|
53
|
+
scope: true,
|
|
54
|
+
files: true,
|
|
55
|
+
transpileOnly: true,
|
|
56
|
+
ignore: ["(?:^|/)node_modules/", `(?:^|/)${distPath}/`]
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
debug("use @babel/register");
|
|
60
|
+
const babelConfig = resolveBabelConfig(
|
|
61
|
+
projectRoot,
|
|
62
|
+
{
|
|
63
|
+
...config.source,
|
|
64
|
+
babelConfig: (_b = config.tools) == null ? void 0 : _b.babel,
|
|
65
|
+
server: {
|
|
66
|
+
compiler: (_c = config.server) == null ? void 0 : _c.compiler
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
tsconfigPath,
|
|
71
|
+
syntax: "es6+",
|
|
72
|
+
type: "commonjs"
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
return require("@babel/register")({
|
|
76
|
+
...babelConfig,
|
|
77
|
+
only: [
|
|
78
|
+
function(filePath) {
|
|
79
|
+
if (filePath.includes(`node_modules${path.sep}.modern-js`)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return registerDirs.some(
|
|
83
|
+
(registerDir) => filePath.startsWith(path.join(projectRoot, registerDir))
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
extensions: [".js", ".ts"],
|
|
88
|
+
babelrc: false,
|
|
89
|
+
configFile: false,
|
|
90
|
+
root: projectRoot
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
export {
|
|
95
|
+
enableRegister
|
|
96
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import minimatch from "minimatch";
|
|
2
|
+
const defaultIgnores = [
|
|
3
|
+
"**/bower_components/**",
|
|
4
|
+
"**/coverage/**",
|
|
5
|
+
"**/node_modules/**",
|
|
6
|
+
"**/.*/**",
|
|
7
|
+
"**/*.d.ts",
|
|
8
|
+
"**/*.log"
|
|
9
|
+
];
|
|
10
|
+
class DependencyTree {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.tree = /* @__PURE__ */ new Map();
|
|
13
|
+
this.ignore = [...defaultIgnores];
|
|
14
|
+
}
|
|
15
|
+
getNode(path) {
|
|
16
|
+
return this.tree.get(path);
|
|
17
|
+
}
|
|
18
|
+
update(cache) {
|
|
19
|
+
this.tree.clear();
|
|
20
|
+
Object.keys(cache).forEach((path) => {
|
|
21
|
+
if (!this.shouldIgnore(path)) {
|
|
22
|
+
const module = cache[path];
|
|
23
|
+
this.tree.set(module.filename, {
|
|
24
|
+
module,
|
|
25
|
+
parent: /* @__PURE__ */ new Set(),
|
|
26
|
+
children: /* @__PURE__ */ new Set()
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
for (const treeNode of this.tree.values()) {
|
|
31
|
+
const { parent } = treeNode.module;
|
|
32
|
+
const { children } = treeNode.module;
|
|
33
|
+
if (parent && !this.shouldIgnore(parent.filename)) {
|
|
34
|
+
const parentTreeNode = this.tree.get(parent.filename);
|
|
35
|
+
if (parentTreeNode) {
|
|
36
|
+
treeNode.parent.add(parentTreeNode);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
children.forEach((child) => {
|
|
40
|
+
if (!this.shouldIgnore(child.filename)) {
|
|
41
|
+
const childTreeNode = this.tree.get(child.filename);
|
|
42
|
+
if (childTreeNode) {
|
|
43
|
+
treeNode.children.add(childTreeNode);
|
|
44
|
+
childTreeNode.parent.add(treeNode);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
shouldIgnore(path) {
|
|
51
|
+
return !path || Boolean(
|
|
52
|
+
this.ignore.find((rule) => minimatch.match([path], rule).length > 0)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
DependencyTree,
|
|
58
|
+
defaultIgnores
|
|
59
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fs, chokidar } from "@modern-js/utils";
|
|
3
|
+
import { DependencyTree } from "./dependency-tree";
|
|
4
|
+
import { StatsCache } from "./stats-cache";
|
|
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 : [ignored]
|
|
28
|
+
] : ignored;
|
|
29
|
+
if (finalIgnored) {
|
|
30
|
+
watchOptions.ignored = finalIgnored;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const finalWatchOptions = {
|
|
34
|
+
...defaultWatchOptions,
|
|
35
|
+
...watchOptions
|
|
36
|
+
};
|
|
37
|
+
return finalWatchOptions;
|
|
38
|
+
};
|
|
39
|
+
class Watcher {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.dependencyTree = null;
|
|
42
|
+
}
|
|
43
|
+
listen(files, options, callback) {
|
|
44
|
+
const watched = files.filter(Boolean);
|
|
45
|
+
const filenames = watched.map((filename) => filename.replace(/\\/g, "/"));
|
|
46
|
+
const cache = new StatsCache();
|
|
47
|
+
const watcher = chokidar.watch(filenames, options);
|
|
48
|
+
watcher.on("ready", () => {
|
|
49
|
+
cache.add(getWatchedFiles(watcher));
|
|
50
|
+
});
|
|
51
|
+
watcher.on("change", (changed) => {
|
|
52
|
+
if (!fs.existsSync(changed) || cache.isDiff(changed)) {
|
|
53
|
+
cache.refresh(changed);
|
|
54
|
+
callback(changed, "change");
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
watcher.on("add", (changed) => {
|
|
58
|
+
if (!cache.has(changed)) {
|
|
59
|
+
cache.add([changed]);
|
|
60
|
+
callback(changed, "add");
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
watcher.on("unlink", (changed) => {
|
|
64
|
+
cache.del(changed);
|
|
65
|
+
callback(changed, "unlink");
|
|
66
|
+
});
|
|
67
|
+
this.watcher = watcher;
|
|
68
|
+
}
|
|
69
|
+
createDepTree() {
|
|
70
|
+
this.dependencyTree = new DependencyTree();
|
|
71
|
+
}
|
|
72
|
+
updateDepTree() {
|
|
73
|
+
var _a;
|
|
74
|
+
(_a = this.dependencyTree) == null ? void 0 : _a.update(require.cache);
|
|
75
|
+
}
|
|
76
|
+
cleanDepCache(filepath) {
|
|
77
|
+
var _a;
|
|
78
|
+
const node = (_a = this.dependencyTree) == null ? void 0 : _a.getNode(filepath);
|
|
79
|
+
if (node && require.cache[filepath]) {
|
|
80
|
+
delete require.cache[filepath];
|
|
81
|
+
for (const parentNode of node.parent.values()) {
|
|
82
|
+
this.cleanDepCache(parentNode.module.filename);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
close() {
|
|
87
|
+
return this.watcher.close();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
Watcher as default,
|
|
92
|
+
defaultWatchOptions,
|
|
93
|
+
getWatchedFiles,
|
|
94
|
+
mergeWatchOptions
|
|
95
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
class StatsCache {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.cachedHash = {};
|
|
6
|
+
this.cachedSize = {};
|
|
7
|
+
}
|
|
8
|
+
add(files) {
|
|
9
|
+
const { cachedHash, cachedSize } = this;
|
|
10
|
+
for (const filename of files) {
|
|
11
|
+
if (fs.existsSync(filename)) {
|
|
12
|
+
const stats = fs.statSync(filename);
|
|
13
|
+
if (stats.isFile() && !cachedHash[filename]) {
|
|
14
|
+
cachedHash[filename] = this.hash(stats, filename);
|
|
15
|
+
cachedSize[filename] = stats.size;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
refresh(filename) {
|
|
21
|
+
const { cachedHash, cachedSize } = this;
|
|
22
|
+
if (fs.existsSync(filename)) {
|
|
23
|
+
const stats = fs.statSync(filename);
|
|
24
|
+
if (stats.isFile()) {
|
|
25
|
+
cachedHash[filename] = this.hash(stats, filename);
|
|
26
|
+
cachedSize[filename] = stats.size;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
del(filename) {
|
|
31
|
+
if (this.cachedHash[filename]) {
|
|
32
|
+
delete this.cachedHash[filename];
|
|
33
|
+
delete this.cachedSize[filename];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
isDiff(filename) {
|
|
37
|
+
const { cachedHash, cachedSize } = this;
|
|
38
|
+
const stats = fs.statSync(filename);
|
|
39
|
+
const hash = cachedHash[filename];
|
|
40
|
+
const size = cachedSize[filename];
|
|
41
|
+
if (stats.size !== size) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
if (this.hash(stats, filename) !== hash) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
has(filename) {
|
|
50
|
+
return Boolean(this.cachedHash[filename]);
|
|
51
|
+
}
|
|
52
|
+
hash(stats, filename) {
|
|
53
|
+
return crypto.createHash("md5").update(fs.readFileSync(filename)).digest("hex");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
StatsCache
|
|
58
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DevServer as Server } from "./server";
|
|
2
|
+
var src_default = (options) => {
|
|
3
|
+
if (options == null) {
|
|
4
|
+
throw new Error("can not start server without options");
|
|
5
|
+
}
|
|
6
|
+
const server = new Server(options);
|
|
7
|
+
return server.init();
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
Server,
|
|
11
|
+
src_default as default
|
|
12
|
+
};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { createServer } from "http";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { createServer as createHttpsServer } from "https";
|
|
4
|
+
import {
|
|
5
|
+
API_DIR,
|
|
6
|
+
SERVER_BUNDLE_DIRECTORY,
|
|
7
|
+
SERVER_DIR,
|
|
8
|
+
SHARED_DIR
|
|
9
|
+
} from "@modern-js/utils";
|
|
10
|
+
import {
|
|
11
|
+
createProxyHandler,
|
|
12
|
+
ModernServer,
|
|
13
|
+
AGGRED_DIR
|
|
14
|
+
} from "@modern-js/prod-server";
|
|
15
|
+
import { LOADABLE_STATS_FILE } from "@modern-js/utils/constants";
|
|
16
|
+
import { getDefaultDevOptions } from "../constants";
|
|
17
|
+
import { createMockHandler } from "../dev-tools/mock";
|
|
18
|
+
import { enableRegister } from "../dev-tools/register";
|
|
19
|
+
import Watcher, { mergeWatchOptions } from "../dev-tools/watcher";
|
|
20
|
+
import DevMiddleware from "../dev-tools/dev-middleware";
|
|
21
|
+
class ModernDevServer extends ModernServer {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
super(options);
|
|
24
|
+
this.mockHandler = null;
|
|
25
|
+
this.workDir = this.pwd;
|
|
26
|
+
this.dev = this.getDevOptions(options);
|
|
27
|
+
this.devMiddleware = new DevMiddleware({
|
|
28
|
+
dev: this.dev,
|
|
29
|
+
devMiddleware: options.devMiddleware
|
|
30
|
+
});
|
|
31
|
+
enableRegister(this.pwd, this.conf);
|
|
32
|
+
}
|
|
33
|
+
getDevOptions(options) {
|
|
34
|
+
const devOptions = typeof options.dev === "boolean" ? {} : options.dev;
|
|
35
|
+
const defaultOptions = getDefaultDevOptions();
|
|
36
|
+
return {
|
|
37
|
+
...defaultOptions,
|
|
38
|
+
...devOptions,
|
|
39
|
+
client: {
|
|
40
|
+
...defaultOptions.client,
|
|
41
|
+
...devOptions == null ? void 0 : devOptions.client
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
addMiddlewareHandler(handlers) {
|
|
46
|
+
handlers.forEach((handler) => {
|
|
47
|
+
this.addHandler((ctx, next) => {
|
|
48
|
+
const { req, res } = ctx;
|
|
49
|
+
return handler(req, res, next);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
applySetupMiddlewares() {
|
|
54
|
+
const setupMiddlewares = this.dev.setupMiddlewares || [];
|
|
55
|
+
const serverOptions = {
|
|
56
|
+
sockWrite: (type, data) => this.devMiddleware.sockWrite(type, data)
|
|
57
|
+
};
|
|
58
|
+
const befores = [];
|
|
59
|
+
const afters = [];
|
|
60
|
+
setupMiddlewares.forEach((handler) => {
|
|
61
|
+
handler(
|
|
62
|
+
{
|
|
63
|
+
unshift: (...handlers) => befores.unshift(...handlers),
|
|
64
|
+
push: (...handlers) => afters.push(...handlers)
|
|
65
|
+
},
|
|
66
|
+
serverOptions
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
return { befores, afters };
|
|
70
|
+
}
|
|
71
|
+
async onInit(runner, app) {
|
|
72
|
+
this.runner = runner;
|
|
73
|
+
const { dev } = this;
|
|
74
|
+
const { befores, afters } = this.applySetupMiddlewares();
|
|
75
|
+
const beforeHandlers = await this.setupBeforeDevMiddleware();
|
|
76
|
+
this.addMiddlewareHandler([...beforeHandlers, ...befores]);
|
|
77
|
+
await this.applyDefaultMiddlewares(app);
|
|
78
|
+
const afterHandlers = await this.setupAfterDevMiddleware();
|
|
79
|
+
this.addMiddlewareHandler([...afters, ...afterHandlers]);
|
|
80
|
+
await super.onInit(runner, app);
|
|
81
|
+
if (dev.watch) {
|
|
82
|
+
this.startWatcher();
|
|
83
|
+
app.on("close", async () => {
|
|
84
|
+
var _a;
|
|
85
|
+
await ((_a = this.watcher) == null ? void 0 : _a.close());
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async applyDefaultMiddlewares(app) {
|
|
90
|
+
const { pwd, dev, devMiddleware } = this;
|
|
91
|
+
this.addHandler((ctx, next) => {
|
|
92
|
+
ctx.res.setHeader("Access-Control-Allow-Origin", "*");
|
|
93
|
+
if (ctx.path.includes("hot-update")) {
|
|
94
|
+
ctx.res.setHeader("Access-Control-Allow-Credentials", "false");
|
|
95
|
+
}
|
|
96
|
+
const confHeaders = dev.headers;
|
|
97
|
+
if (confHeaders) {
|
|
98
|
+
for (const [key, value] of Object.entries(confHeaders)) {
|
|
99
|
+
ctx.res.setHeader(key, value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
next();
|
|
103
|
+
});
|
|
104
|
+
this.mockHandler = createMockHandler({ pwd });
|
|
105
|
+
this.addHandler((ctx, next) => {
|
|
106
|
+
if (this.mockHandler) {
|
|
107
|
+
this.mockHandler(ctx, next);
|
|
108
|
+
} else {
|
|
109
|
+
next();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
const proxyHandlers = createProxyHandler(dev.proxy);
|
|
113
|
+
if (proxyHandlers) {
|
|
114
|
+
proxyHandlers.forEach((handler) => {
|
|
115
|
+
this.addHandler(handler);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
devMiddleware.init(app);
|
|
119
|
+
devMiddleware.on("change", (stats) => {
|
|
120
|
+
if (stats.toJson({ all: false }).name === "client") {
|
|
121
|
+
this.onRepack({ routes: this.getRoutes() });
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
this.addHandler((ctx, next) => {
|
|
125
|
+
const { req, res } = ctx;
|
|
126
|
+
if (devMiddleware.middleware) {
|
|
127
|
+
devMiddleware.middleware(req, res, next);
|
|
128
|
+
} else {
|
|
129
|
+
next();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
if (dev.historyApiFallback) {
|
|
133
|
+
const { default: connectHistoryApiFallback } = await import("connect-history-api-fallback");
|
|
134
|
+
const historyApiFallbackMiddleware = connectHistoryApiFallback(
|
|
135
|
+
typeof dev.historyApiFallback === "boolean" ? {} : dev.historyApiFallback
|
|
136
|
+
);
|
|
137
|
+
this.addHandler(
|
|
138
|
+
(ctx, next) => historyApiFallbackMiddleware(ctx.req, ctx.res, next)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
onRepack(options = {}) {
|
|
143
|
+
if (Array.isArray(options.routes)) {
|
|
144
|
+
this.router.reset(this.filterRoutes(options.routes));
|
|
145
|
+
}
|
|
146
|
+
this.cleanSSRCache();
|
|
147
|
+
this.reader.updateFile();
|
|
148
|
+
this.runner.repack();
|
|
149
|
+
super.onRepack(options);
|
|
150
|
+
}
|
|
151
|
+
async createHTTPServer(handler) {
|
|
152
|
+
const { dev } = this;
|
|
153
|
+
const devHttpsOption = typeof dev === "object" && dev.https;
|
|
154
|
+
if (devHttpsOption) {
|
|
155
|
+
const { genHttpsOptions } = require("../dev-tools/https");
|
|
156
|
+
const httpsOptions = await genHttpsOptions(devHttpsOption, this.pwd);
|
|
157
|
+
return createHttpsServer(httpsOptions, handler);
|
|
158
|
+
} else {
|
|
159
|
+
return createServer(handler);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
warmupSSRBundle() {
|
|
163
|
+
}
|
|
164
|
+
onServerChange({
|
|
165
|
+
filepath,
|
|
166
|
+
event
|
|
167
|
+
}) {
|
|
168
|
+
const { pwd } = this;
|
|
169
|
+
const { mock } = AGGRED_DIR;
|
|
170
|
+
const mockPath = path.normalize(path.join(pwd, mock));
|
|
171
|
+
this.runner.reset();
|
|
172
|
+
if (filepath.startsWith(mockPath)) {
|
|
173
|
+
this.mockHandler = createMockHandler({ pwd });
|
|
174
|
+
} else {
|
|
175
|
+
try {
|
|
176
|
+
const success = this.runner.onApiChange([
|
|
177
|
+
{ filename: filepath, event }
|
|
178
|
+
]);
|
|
179
|
+
if (success !== true) {
|
|
180
|
+
super.onServerChange({ filepath });
|
|
181
|
+
}
|
|
182
|
+
} catch (e) {
|
|
183
|
+
this.logger.error(e);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
createContext(req, res) {
|
|
188
|
+
return super.createContext(req, res, { etag: true });
|
|
189
|
+
}
|
|
190
|
+
async setupBeforeDevMiddleware() {
|
|
191
|
+
const { runner, conf, dev } = this;
|
|
192
|
+
const setupMids = dev.before || [];
|
|
193
|
+
const pluginMids = await runner.beforeDevServer(conf);
|
|
194
|
+
return [...setupMids, ...pluginMids].flat();
|
|
195
|
+
}
|
|
196
|
+
async setupAfterDevMiddleware() {
|
|
197
|
+
const { runner, conf, dev } = this;
|
|
198
|
+
const setupMids = dev.after || [];
|
|
199
|
+
const pluginMids = await runner.afterDevServer(conf);
|
|
200
|
+
return [...pluginMids, ...setupMids].flat();
|
|
201
|
+
}
|
|
202
|
+
cleanSSRCache() {
|
|
203
|
+
const { distDir } = this;
|
|
204
|
+
const bundles = this.router.getBundles();
|
|
205
|
+
bundles.forEach((bundle) => {
|
|
206
|
+
const filepath = path.join(distDir, bundle);
|
|
207
|
+
if (require.cache[filepath]) {
|
|
208
|
+
delete require.cache[filepath];
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
const loadable = path.join(distDir, LOADABLE_STATS_FILE);
|
|
212
|
+
if (require.cache[loadable]) {
|
|
213
|
+
delete require.cache[loadable];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
startWatcher() {
|
|
217
|
+
var _a;
|
|
218
|
+
const { pwd, distDir } = this;
|
|
219
|
+
const { mock } = AGGRED_DIR;
|
|
220
|
+
const defaultWatched = [
|
|
221
|
+
`${mock}/**/*`,
|
|
222
|
+
`${SERVER_DIR}/**/*`,
|
|
223
|
+
`${API_DIR}/**`,
|
|
224
|
+
`${SHARED_DIR}/**/*`,
|
|
225
|
+
`${distDir}/${SERVER_BUNDLE_DIRECTORY}/*-server-loaders.js`
|
|
226
|
+
];
|
|
227
|
+
const watchOptions = mergeWatchOptions((_a = this.conf.server) == null ? void 0 : _a.watchOptions);
|
|
228
|
+
const defaultWatchedPaths = defaultWatched.map((p) => {
|
|
229
|
+
const finalPath = path.isAbsolute(p) ? p : path.join(pwd, p);
|
|
230
|
+
return path.normalize(finalPath);
|
|
231
|
+
});
|
|
232
|
+
const watcher = new Watcher();
|
|
233
|
+
watcher.createDepTree();
|
|
234
|
+
watcher.listen(defaultWatchedPaths, watchOptions, (filepath, event) => {
|
|
235
|
+
watcher.updateDepTree();
|
|
236
|
+
watcher.cleanDepCache(filepath);
|
|
237
|
+
this.onServerChange({
|
|
238
|
+
filepath,
|
|
239
|
+
event
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
this.watcher = watcher;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
export {
|
|
246
|
+
ModernDevServer
|
|
247
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Server } from "@modern-js/prod-server";
|
|
2
|
+
import { ModernDevServer } from "./dev-server";
|
|
3
|
+
const createDevServer = (options) => {
|
|
4
|
+
return new ModernDevServer(options);
|
|
5
|
+
};
|
|
6
|
+
class DevServer extends Server {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
super(options);
|
|
9
|
+
if (options.dev) {
|
|
10
|
+
this.serverImpl = createDevServer;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
DevServer
|
|
16
|
+
};
|
|
File without changes
|
|
@@ -10,14 +10,11 @@ var require_hmr_client = __commonJS({
|
|
|
10
10
|
const hadRuntimeError = false;
|
|
11
11
|
const socketUrl = createSocketUrl(__resourceQuery);
|
|
12
12
|
const connection = new WebSocket(socketUrl);
|
|
13
|
-
connection.onopen = function() {
|
|
14
|
-
if (typeof console !== "undefined" && typeof console.debug === "function") {
|
|
15
|
-
console.debug("[HMR] connected.");
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
13
|
connection.onclose = function() {
|
|
19
14
|
if (typeof console !== "undefined" && typeof console.info === "function") {
|
|
20
|
-
console.
|
|
15
|
+
console.info(
|
|
16
|
+
"The development server has disconnected.\nRefresh the page if necessary."
|
|
17
|
+
);
|
|
21
18
|
}
|
|
22
19
|
};
|
|
23
20
|
let isFirstCompilation = true;
|
|
@@ -22,14 +22,11 @@ var import_createSocketUrl = require("./createSocketUrl");
|
|
|
22
22
|
const hadRuntimeError = false;
|
|
23
23
|
const socketUrl = (0, import_createSocketUrl.createSocketUrl)(__resourceQuery);
|
|
24
24
|
const connection = new WebSocket(socketUrl);
|
|
25
|
-
connection.onopen = function() {
|
|
26
|
-
if (typeof console !== "undefined" && typeof console.debug === "function") {
|
|
27
|
-
console.debug("[HMR] connected.");
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
25
|
connection.onclose = function() {
|
|
31
26
|
if (typeof console !== "undefined" && typeof console.info === "function") {
|
|
32
|
-
console.
|
|
27
|
+
console.info(
|
|
28
|
+
"The development server has disconnected.\nRefresh the page if necessary."
|
|
29
|
+
);
|
|
33
30
|
}
|
|
34
31
|
};
|
|
35
32
|
let isFirstCompilation = true;
|
|
@@ -95,14 +95,9 @@ var require_hmr_client = __commonJS({
|
|
|
95
95
|
var hadRuntimeError = false;
|
|
96
96
|
var socketUrl = createSocketUrl(__resourceQuery);
|
|
97
97
|
var connection = new WebSocket(socketUrl);
|
|
98
|
-
connection.onopen = function() {
|
|
99
|
-
if (typeof console !== "undefined" && typeof console.debug === "function") {
|
|
100
|
-
console.debug("[HMR] connected.");
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
98
|
connection.onclose = function() {
|
|
104
99
|
if (typeof console !== "undefined" && typeof console.info === "function") {
|
|
105
|
-
console.
|
|
100
|
+
console.info("The development server has disconnected.\nRefresh the page if necessary.");
|
|
106
101
|
}
|
|
107
102
|
};
|
|
108
103
|
var isFirstCompilation = true;
|
|
@@ -275,9 +275,9 @@ var DevMiddleware = /*#__PURE__*/ function(EventEmitter) {
|
|
|
275
275
|
});
|
|
276
276
|
var _this1 = this;
|
|
277
277
|
app.on("close", /*#__PURE__*/ _asyncToGenerator(function() {
|
|
278
|
-
var
|
|
278
|
+
var ref;
|
|
279
279
|
return __generator(this, function(_state) {
|
|
280
|
-
(
|
|
280
|
+
(ref = _this1.middleware) === null || ref === void 0 ? void 0 : ref.close(noop);
|
|
281
281
|
_this1.socketServer.close();
|
|
282
282
|
return [
|
|
283
283
|
2
|
|
@@ -49,11 +49,11 @@ var SocketServer = /*#__PURE__*/ function() {
|
|
|
49
49
|
key: "prepare",
|
|
50
50
|
value: function prepare(app) {
|
|
51
51
|
var _this = this;
|
|
52
|
-
var
|
|
52
|
+
var ref;
|
|
53
53
|
this.app = app;
|
|
54
54
|
this.wsServer = new ws.Server({
|
|
55
55
|
noServer: true,
|
|
56
|
-
path: (
|
|
56
|
+
path: (ref = this.options.client) === null || ref === void 0 ? void 0 : ref.path
|
|
57
57
|
});
|
|
58
58
|
this.app.on("upgrade", function(req, sock, head) {
|
|
59
59
|
if (!_this.wsServer.shouldHandle(req)) {
|