oipage 1.3.1-alpha.0 → 1.3.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.
- package/.github/FUNDING.yml +11 -11
- package/AUTHORS.txt +6 -6
- package/CHANGELOG +76 -75
- package/LICENSE +20 -20
- package/README.md +80 -80
- package/bin/data/mineTypes.json +104 -104
- package/bin/disk.js +31 -31
- package/bin/help.js +24 -24
- package/bin/intercept.js +15 -15
- package/bin/run +96 -96
- package/bin/serve.js +128 -128
- package/bin/template/404.html +171 -171
- package/bin/tools/format.js +75 -75
- package/bin/tools/network.js +42 -42
- package/bin/tools/resolve404.js +83 -83
- package/bin/tools/resolveImport.js +88 -88
- package/nodejs/animation/index.d.ts +19 -19
- package/nodejs/animation/index.js +104 -104
- package/nodejs/cmdlog/index.d.ts +20 -20
- package/nodejs/cmdlog/index.js +75 -75
- package/nodejs/disk/index.d.ts +16 -16
- package/nodejs/disk/index.js +78 -78
- package/nodejs/json/index.d.ts +9 -9
- package/nodejs/json/index.js +206 -206
- package/nodejs/logform/index.d.ts +18 -18
- package/nodejs/logform/index.js +94 -94
- package/nodejs/reader/index.d.ts +32 -32
- package/nodejs/reader/index.js +20 -20
- package/nodejs/throttle/index.d.ts +30 -30
- package/nodejs/throttle/index.js +50 -50
- package/package.json +40 -40
- package/web/animation/index.d.ts +19 -19
- package/web/animation/index.js +104 -104
- package/web/json/index.d.ts +9 -9
- package/web/json/index.js +206 -206
- package/web/onReady/index.d.ts +7 -7
- package/web/onReady/index.js +8 -8
- package/web/performChunk/index.d.ts +4 -4
- package/web/performChunk/index.js +19 -19
- package/web/reader/index.d.ts +32 -32
- package/web/reader/index.js +20 -20
- package/web/style/index.d.ts +21 -21
- package/web/style/index.js +19 -19
- package/web/throttle/index.d.ts +30 -30
- package/web/throttle/index.js +50 -50
package/bin/disk.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
const { deleteDisk, copyDisk } = require("../nodejs/disk");
|
|
2
|
-
|
|
3
|
-
module.exports = function (config) {
|
|
4
|
-
let isForce = false;
|
|
5
|
-
|
|
6
|
-
// 判断是否开启强制执行
|
|
7
|
-
for (let i = 0; i < config.value.length; i++) {
|
|
8
|
-
if (config.value[i].name === "--force") isForce = true;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// 执行一个个任务
|
|
12
|
-
for (let i = 0; i < config.value.length; i++) {
|
|
13
|
-
|
|
14
|
-
// 删除文件或文件夹
|
|
15
|
-
if (config.value[i].name === "--delete") {
|
|
16
|
-
for (let j = 0; j < config.value[i].value.length; j++) {
|
|
17
|
-
deleteDisk(config.value[i].value[j]);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// 移动文件或文件夹
|
|
22
|
-
else if (config.value[i].name === "--move") {
|
|
23
|
-
copyDisk(config.value[i].value[0], config.value[i].value[1], isForce);
|
|
24
|
-
deleteDisk(config.value[i].value[0]);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 复制文件或文件夹
|
|
28
|
-
else if (config.value[i].name === "--copy") {
|
|
29
|
-
copyDisk(config.value[i].value[0], config.value[i].value[1], isForce);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
1
|
+
const { deleteDisk, copyDisk } = require("../nodejs/disk");
|
|
2
|
+
|
|
3
|
+
module.exports = function (config) {
|
|
4
|
+
let isForce = false;
|
|
5
|
+
|
|
6
|
+
// 判断是否开启强制执行
|
|
7
|
+
for (let i = 0; i < config.value.length; i++) {
|
|
8
|
+
if (config.value[i].name === "--force") isForce = true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 执行一个个任务
|
|
12
|
+
for (let i = 0; i < config.value.length; i++) {
|
|
13
|
+
|
|
14
|
+
// 删除文件或文件夹
|
|
15
|
+
if (config.value[i].name === "--delete") {
|
|
16
|
+
for (let j = 0; j < config.value[i].value.length; j++) {
|
|
17
|
+
deleteDisk(config.value[i].value[j]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 移动文件或文件夹
|
|
22
|
+
else if (config.value[i].name === "--move") {
|
|
23
|
+
copyDisk(config.value[i].value[0], config.value[i].value[1], isForce);
|
|
24
|
+
deleteDisk(config.value[i].value[0]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 复制文件或文件夹
|
|
28
|
+
else if (config.value[i].name === "--copy") {
|
|
29
|
+
copyDisk(config.value[i].value[0], config.value[i].value[1], isForce);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
32
|
};
|
package/bin/help.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
const packageValue = require("../package.json");
|
|
2
|
-
|
|
3
|
-
module.exports = function () {
|
|
4
|
-
console.log(`\x1b[36m
|
|
5
|
-
OIPage@v${packageValue.version}
|
|
6
|
-
|
|
7
|
-
可以使用的命令如下:
|
|
8
|
-
|
|
9
|
-
【1】oipage-cli serve 开发服务器
|
|
10
|
-
--port|-p 端口号
|
|
11
|
-
--baseUrl 服务器根目录
|
|
12
|
-
--config|-c 设置配置文件
|
|
13
|
-
|
|
14
|
-
【2】oipage-cli disk 磁盘操作
|
|
15
|
-
--force|-f 强制执行
|
|
16
|
-
--delete|-d 删除文件或文件夹
|
|
17
|
-
--move|m 移动文件或文件夹
|
|
18
|
-
--copy|-c 复制文件或文件夹
|
|
19
|
-
|
|
20
|
-
【3】oipage-cli run "任务一" "任务二" ... 运行多命令
|
|
21
|
-
|
|
22
|
-
Powered by https://github.com/zxl20070701
|
|
23
|
-
\x1b[0m`);
|
|
24
|
-
|
|
1
|
+
const packageValue = require("../package.json");
|
|
2
|
+
|
|
3
|
+
module.exports = function () {
|
|
4
|
+
console.log(`\x1b[36m
|
|
5
|
+
OIPage@v${packageValue.version}
|
|
6
|
+
|
|
7
|
+
可以使用的命令如下:
|
|
8
|
+
|
|
9
|
+
【1】oipage-cli serve 开发服务器
|
|
10
|
+
--port|-p 端口号
|
|
11
|
+
--baseUrl 服务器根目录
|
|
12
|
+
--config|-c 设置配置文件
|
|
13
|
+
|
|
14
|
+
【2】oipage-cli disk 磁盘操作
|
|
15
|
+
--force|-f 强制执行
|
|
16
|
+
--delete|-d 删除文件或文件夹
|
|
17
|
+
--move|m 移动文件或文件夹
|
|
18
|
+
--copy|-c 复制文件或文件夹
|
|
19
|
+
|
|
20
|
+
【3】oipage-cli run "任务一" "任务二" ... 运行多命令
|
|
21
|
+
|
|
22
|
+
Powered by https://github.com/zxl20070701
|
|
23
|
+
\x1b[0m`);
|
|
24
|
+
|
|
25
25
|
};
|
package/bin/intercept.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
exports.doIntercept = function (url, intercept, request, response) {
|
|
2
|
-
for (let item of intercept) {
|
|
3
|
-
if (item.test.test(url)) {
|
|
4
|
-
item.handler(request, response);
|
|
5
|
-
return true;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
exports.testIntercept = function (url, intercept) {
|
|
11
|
-
for (let item of intercept) {
|
|
12
|
-
if (item.test.test(url)) {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
1
|
+
exports.doIntercept = function (url, intercept, request, response) {
|
|
2
|
+
for (let item of intercept) {
|
|
3
|
+
if (item.test.test(url)) {
|
|
4
|
+
item.handler(request, response);
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
exports.testIntercept = function (url, intercept) {
|
|
11
|
+
for (let item of intercept) {
|
|
12
|
+
if (item.test.test(url)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
16
|
}
|
package/bin/run
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
process.title = 'OIPage';
|
|
6
|
-
|
|
7
|
-
const { exec } = require('child_process');
|
|
8
|
-
const { join } = require("path");
|
|
9
|
-
const { existsSync, lstatSync } = require("fs");
|
|
10
|
-
const { mergeOption } = require("vislite");
|
|
11
|
-
const { formatArgv } = require("./tools/format.js");
|
|
12
|
-
|
|
13
|
-
// 开发服务器
|
|
14
|
-
if (process.argv[2] === "serve") {
|
|
15
|
-
|
|
16
|
-
let argvObj = formatArgv(process.argv, {
|
|
17
|
-
"-p": "--port",
|
|
18
|
-
"-c": "--config"
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
let config = {
|
|
22
|
-
devServer: {
|
|
23
|
-
port: 8080,
|
|
24
|
-
baseUrl: "./",
|
|
25
|
-
intercept: []
|
|
26
|
-
},
|
|
27
|
-
module: {
|
|
28
|
-
rules: []
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// 如果设置了配置文件
|
|
33
|
-
if (argvObj["--config"]) {
|
|
34
|
-
let configPath = join(process.cwd(), argvObj["--config"][0] || "./oipage.config.js");
|
|
35
|
-
if (existsSync(configPath) && !lstatSync(configPath).isDirectory()) {
|
|
36
|
-
let configValue = require(configPath);
|
|
37
|
-
mergeOption(config, configValue);
|
|
38
|
-
} else {
|
|
39
|
-
console.log("\x1b[0m\x1b[31m" + configPath + "\x1b[0m");
|
|
40
|
-
throw new Error("OIPage: The configuration file does not exist or is not a file.");
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if ((argvObj["--port"] || [])[0]) config.devServer.port = (argvObj["--port"] || [])[0];
|
|
45
|
-
if ((argvObj["--baseUrl"] || [])[0]) config.devServer.baseUrl = (argvObj["--baseUrl"] || [])[0];
|
|
46
|
-
|
|
47
|
-
require("./serve.js")(config);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// 磁盘操作
|
|
51
|
-
else if (process.argv[2] === "disk") {
|
|
52
|
-
|
|
53
|
-
let argvObj = formatArgv(process.argv, {
|
|
54
|
-
"-f": "--force",
|
|
55
|
-
"-d": "--delete",
|
|
56
|
-
"-m": "--move",
|
|
57
|
-
"-c": "--copy"
|
|
58
|
-
}, true);
|
|
59
|
-
|
|
60
|
-
require("./disk.js")(argvObj);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 运行多命令
|
|
64
|
-
else if (process.argv[2] === "run") {
|
|
65
|
-
|
|
66
|
-
let argvObj = formatArgv(process.argv, {});
|
|
67
|
-
|
|
68
|
-
for (let index = 0; index < argvObj.args.length; index++) {
|
|
69
|
-
const child = exec(argvObj.args[index]);
|
|
70
|
-
|
|
71
|
-
// 监听子线程的stdout
|
|
72
|
-
child.stdout.on('data', (data) => {
|
|
73
|
-
console.log(`[${index + 1}] log:${data}`);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// 监听子线程的stderr
|
|
77
|
-
child.stderr.on('data', (data) => {
|
|
78
|
-
console.error(`[${index + 1}] error:${data}`);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// 子线程结束处理
|
|
82
|
-
child.on('close', (code) => {
|
|
83
|
-
console.log(`[${index + 1}] 子线程结束,退出码 ${code}`);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// 子线程出错处理
|
|
87
|
-
child.on('error', (error) => {
|
|
88
|
-
console.error(`[${index + 1}] 子线程错误: ${error.message}`);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// 默认,帮助
|
|
95
|
-
else {
|
|
96
|
-
require("./help.js")();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
process.title = 'OIPage';
|
|
6
|
+
|
|
7
|
+
const { exec } = require('child_process');
|
|
8
|
+
const { join } = require("path");
|
|
9
|
+
const { existsSync, lstatSync } = require("fs");
|
|
10
|
+
const { mergeOption } = require("vislite");
|
|
11
|
+
const { formatArgv } = require("./tools/format.js");
|
|
12
|
+
|
|
13
|
+
// 开发服务器
|
|
14
|
+
if (process.argv[2] === "serve") {
|
|
15
|
+
|
|
16
|
+
let argvObj = formatArgv(process.argv, {
|
|
17
|
+
"-p": "--port",
|
|
18
|
+
"-c": "--config"
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
let config = {
|
|
22
|
+
devServer: {
|
|
23
|
+
port: 8080,
|
|
24
|
+
baseUrl: "./",
|
|
25
|
+
intercept: []
|
|
26
|
+
},
|
|
27
|
+
module: {
|
|
28
|
+
rules: []
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// 如果设置了配置文件
|
|
33
|
+
if (argvObj["--config"]) {
|
|
34
|
+
let configPath = join(process.cwd(), argvObj["--config"][0] || "./oipage.config.js");
|
|
35
|
+
if (existsSync(configPath) && !lstatSync(configPath).isDirectory()) {
|
|
36
|
+
let configValue = require(configPath);
|
|
37
|
+
mergeOption(config, configValue);
|
|
38
|
+
} else {
|
|
39
|
+
console.log("\x1b[0m\x1b[31m" + configPath + "\x1b[0m");
|
|
40
|
+
throw new Error("OIPage: The configuration file does not exist or is not a file.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if ((argvObj["--port"] || [])[0]) config.devServer.port = (argvObj["--port"] || [])[0];
|
|
45
|
+
if ((argvObj["--baseUrl"] || [])[0]) config.devServer.baseUrl = (argvObj["--baseUrl"] || [])[0];
|
|
46
|
+
|
|
47
|
+
require("./serve.js")(config);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 磁盘操作
|
|
51
|
+
else if (process.argv[2] === "disk") {
|
|
52
|
+
|
|
53
|
+
let argvObj = formatArgv(process.argv, {
|
|
54
|
+
"-f": "--force",
|
|
55
|
+
"-d": "--delete",
|
|
56
|
+
"-m": "--move",
|
|
57
|
+
"-c": "--copy"
|
|
58
|
+
}, true);
|
|
59
|
+
|
|
60
|
+
require("./disk.js")(argvObj);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 运行多命令
|
|
64
|
+
else if (process.argv[2] === "run") {
|
|
65
|
+
|
|
66
|
+
let argvObj = formatArgv(process.argv, {});
|
|
67
|
+
|
|
68
|
+
for (let index = 0; index < argvObj.args.length; index++) {
|
|
69
|
+
const child = exec(argvObj.args[index]);
|
|
70
|
+
|
|
71
|
+
// 监听子线程的stdout
|
|
72
|
+
child.stdout.on('data', (data) => {
|
|
73
|
+
console.log(`[${index + 1}] log:${data}`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 监听子线程的stderr
|
|
77
|
+
child.stderr.on('data', (data) => {
|
|
78
|
+
console.error(`[${index + 1}] error:${data}`);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// 子线程结束处理
|
|
82
|
+
child.on('close', (code) => {
|
|
83
|
+
console.log(`[${index + 1}] 子线程结束,退出码 ${code}`);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// 子线程出错处理
|
|
87
|
+
child.on('error', (error) => {
|
|
88
|
+
console.error(`[${index + 1}] 子线程错误: ${error.message}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 默认,帮助
|
|
95
|
+
else {
|
|
96
|
+
require("./help.js")();
|
|
97
97
|
}
|
package/bin/serve.js
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
const { join } = require("path");
|
|
2
|
-
const { existsSync, lstatSync, statSync, createReadStream } = require("fs");
|
|
3
|
-
const { createServer } = require('http');
|
|
4
|
-
const packageValue = require("../package.json");
|
|
5
|
-
const network = require("./tools/network.js");
|
|
6
|
-
const mineTypes = require("./data/mineTypes.json");
|
|
7
|
-
const resolve404 = require("./tools/resolve404.js");
|
|
8
|
-
const resolveImportFactory = require("./tools/resolveImport.js");
|
|
9
|
-
const { doIntercept } = require("./intercept.js");
|
|
10
|
-
|
|
11
|
-
// 开发服务器
|
|
12
|
-
module.exports = function (config) {
|
|
13
|
-
let startTime = new Date().valueOf();
|
|
14
|
-
|
|
15
|
-
const port = config.devServer.port; // 端口号
|
|
16
|
-
const basePath = (/^\./.test(config.devServer.baseUrl)) ? join(process.cwd(), config.devServer.baseUrl) : config.devServer.baseUrl; // 服务器根路径
|
|
17
|
-
|
|
18
|
-
let Server = createServer(function (request, response) {
|
|
19
|
-
let headers = request.headers;
|
|
20
|
-
let url = decodeURIComponent(request.url);
|
|
21
|
-
|
|
22
|
-
let urlArray = url.split("?");
|
|
23
|
-
url = urlArray[0];
|
|
24
|
-
|
|
25
|
-
// 请求的文件路径
|
|
26
|
-
let filePath = join(basePath, url == "/" ? "index.html" : url.replace(/^\//, ""));
|
|
27
|
-
|
|
28
|
-
// 请求拦截
|
|
29
|
-
if (doIntercept(url.replace(/^\/@modules\//, ""), config.devServer.intercept, request, response)) {
|
|
30
|
-
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] intercept: " + url + '\x1b[0m ' + new Date().toLocaleString());
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 如果存在且是文件
|
|
34
|
-
else if (existsSync(filePath) && !lstatSync(filePath).isDirectory()) {
|
|
35
|
-
|
|
36
|
-
let dotName = /\./.test(filePath) ? filePath.match(/\.([^.]+)$/)[1] : "";
|
|
37
|
-
let fileType = mineTypes[dotName]; // 文件类型
|
|
38
|
-
let fileInfo = statSync(filePath);
|
|
39
|
-
|
|
40
|
-
let fileModifiedTime = new Date(fileInfo.mtime).
|
|
41
|
-
|
|
42
|
-
let responseHeader = {
|
|
43
|
-
'Content-type': (fileType || "text/plain") + ";charset=utf-8",
|
|
44
|
-
'Access-Control-Allow-Origin': '*',
|
|
45
|
-
'Server': 'Powered by OIPage-dev-server@' + packageValue.version,
|
|
46
|
-
'Cache-Control': 'no-cache',
|
|
47
|
-
'Last-Modified': fileModifiedTime
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
if (headers["if-modified-since"]) {
|
|
51
|
-
let ifModifiedSince = new Date(headers["if-modified-since"]).valueOf()
|
|
52
|
-
let lastModified = new Date(fileModifiedTime).valueOf()
|
|
53
|
-
if (lastModified <= ifModifiedSince) {
|
|
54
|
-
response.writeHead('304', responseHeader);
|
|
55
|
-
response.end();
|
|
56
|
-
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] Cache File: " + url + "\x1b[0m " + new Date().toLocaleString() + "\x1b[33m\x1b[1m 304\x1b[0m");
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let sendType = "";
|
|
62
|
-
let entry = headers.accept !== "*/*";
|
|
63
|
-
|
|
64
|
-
// 如果文件小于10M,认为不大,直接读取
|
|
65
|
-
if (fileInfo.size < 10 * 1024 * 1024) {
|
|
66
|
-
let { source, resolveImport } = resolveImportFactory(basePath, filePath, entry, config.devServer.intercept, urlArray[1] === "download")
|
|
67
|
-
|
|
68
|
-
// 只处理非下载文件
|
|
69
|
-
// 过大的也不进行处理
|
|
70
|
-
if (urlArray[1] !== "download") {
|
|
71
|
-
for (let i = 0; i < config.module.rules.length; i++) {
|
|
72
|
-
if (config.module.rules[i].test.test(filePath)) {
|
|
73
|
-
source = config.module.rules[i].use.call({
|
|
74
|
-
root: basePath, // 服务器根路径
|
|
75
|
-
path: filePath.replace(basePath, ""), // 文件相对路径
|
|
76
|
-
entry, // 是否是浏览器地址栏直接访问
|
|
77
|
-
setFileType(_fileType) { // 设置文件类型
|
|
78
|
-
fileType = _fileType;
|
|
79
|
-
responseHeader['Content-type'] = _fileType + ";charset=utf-8";
|
|
80
|
-
}
|
|
81
|
-
}, source);
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
sendType = "Read";
|
|
88
|
-
response.writeHead('200', responseHeader);
|
|
89
|
-
response.write(resolveImport(source, fileType !== "application/javascript"));
|
|
90
|
-
response.end();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// 对于大文件,使用流读取
|
|
94
|
-
else {
|
|
95
|
-
sendType = "Stream";
|
|
96
|
-
responseHeader["Content-Length"] = fileInfo.size;
|
|
97
|
-
response.writeHead('200', responseHeader);
|
|
98
|
-
createReadStream(filePath).pipe(response);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] " + sendType + " File: " + url + '\x1b[0m ' + new Date().toLocaleString());
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// 否则就是404
|
|
105
|
-
else {
|
|
106
|
-
response.writeHead(404, {
|
|
107
|
-
'Content-type': "text/html;charset=utf-8",
|
|
108
|
-
'Access-Control-Allow-Origin': '*',
|
|
109
|
-
'Server': 'Powered by OIPage-dev-server@' + packageValue.version
|
|
110
|
-
});
|
|
111
|
-
response.write(resolve404(filePath, url));
|
|
112
|
-
response.end();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
Server.listen(port);
|
|
118
|
-
|
|
119
|
-
// 获取网络信息
|
|
120
|
-
let networkValue = network();
|
|
121
|
-
|
|
122
|
-
// 打印成功提示
|
|
123
|
-
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Project is running at:\x1b[0m');
|
|
124
|
-
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Loopback: \x1b[36mhttp://localhost:' + port + '/\x1b[0m');
|
|
125
|
-
for (let ipv4Item of networkValue.IPv4) console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] On Your Network (IPv4):\x1b[36m http://' + ipv4Item.address + ':' + port + '/\x1b[0m');
|
|
126
|
-
for (let ipv6Item of networkValue.IPv6) console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] On Your Network (IPv6): \x1b[36mhttp://[' + ipv6Item.address + ']:' + port + '/\x1b[0m');
|
|
127
|
-
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Content not from OIPage is served from \x1b[36m"' + basePath + '" \x1b[0mdirectory');
|
|
128
|
-
console.log('\nOIPage ' + packageValue.version + ' compiled \x1b[1m\x1b[32msuccessfully\x1b[0m in ' + (new Date().valueOf() - startTime) + ' ms\n')
|
|
1
|
+
const { join } = require("path");
|
|
2
|
+
const { existsSync, lstatSync, statSync, createReadStream } = require("fs");
|
|
3
|
+
const { createServer } = require('http');
|
|
4
|
+
const packageValue = require("../package.json");
|
|
5
|
+
const network = require("./tools/network.js");
|
|
6
|
+
const mineTypes = require("./data/mineTypes.json");
|
|
7
|
+
const resolve404 = require("./tools/resolve404.js");
|
|
8
|
+
const resolveImportFactory = require("./tools/resolveImport.js");
|
|
9
|
+
const { doIntercept } = require("./intercept.js");
|
|
10
|
+
|
|
11
|
+
// 开发服务器
|
|
12
|
+
module.exports = function (config) {
|
|
13
|
+
let startTime = new Date().valueOf();
|
|
14
|
+
|
|
15
|
+
const port = config.devServer.port; // 端口号
|
|
16
|
+
const basePath = (/^\./.test(config.devServer.baseUrl)) ? join(process.cwd(), config.devServer.baseUrl) : config.devServer.baseUrl; // 服务器根路径
|
|
17
|
+
|
|
18
|
+
let Server = createServer(function (request, response) {
|
|
19
|
+
let headers = request.headers;
|
|
20
|
+
let url = decodeURIComponent(request.url);
|
|
21
|
+
|
|
22
|
+
let urlArray = url.split("?");
|
|
23
|
+
url = urlArray[0];
|
|
24
|
+
|
|
25
|
+
// 请求的文件路径
|
|
26
|
+
let filePath = join(basePath, url == "/" ? "index.html" : url.replace(/^\//, ""));
|
|
27
|
+
|
|
28
|
+
// 请求拦截
|
|
29
|
+
if (doIntercept(url.replace(/^\/@modules\//, ""), config.devServer.intercept, request, response)) {
|
|
30
|
+
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] intercept: " + url + '\x1b[0m ' + new Date().toLocaleString());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 如果存在且是文件
|
|
34
|
+
else if (existsSync(filePath) && !lstatSync(filePath).isDirectory()) {
|
|
35
|
+
|
|
36
|
+
let dotName = /\./.test(filePath) ? filePath.match(/\.([^.]+)$/)[1] : "";
|
|
37
|
+
let fileType = mineTypes[dotName]; // 文件类型
|
|
38
|
+
let fileInfo = statSync(filePath);
|
|
39
|
+
|
|
40
|
+
let fileModifiedTime = new Date(fileInfo.mtime).toGMTString();
|
|
41
|
+
|
|
42
|
+
let responseHeader = {
|
|
43
|
+
'Content-type': (fileType || "text/plain") + ";charset=utf-8",
|
|
44
|
+
'Access-Control-Allow-Origin': '*',
|
|
45
|
+
'Server': 'Powered by OIPage-dev-server@' + packageValue.version,
|
|
46
|
+
'Cache-Control': 'no-cache',
|
|
47
|
+
'Last-Modified': fileModifiedTime
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (headers["if-modified-since"]) {
|
|
51
|
+
let ifModifiedSince = new Date(headers["if-modified-since"]).valueOf()
|
|
52
|
+
let lastModified = new Date(fileModifiedTime).valueOf()
|
|
53
|
+
if (lastModified <= ifModifiedSince) {
|
|
54
|
+
response.writeHead('304', responseHeader);
|
|
55
|
+
response.end();
|
|
56
|
+
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] Cache File: " + url + "\x1b[0m " + new Date().toLocaleString() + "\x1b[33m\x1b[1m 304\x1b[0m");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let sendType = "";
|
|
62
|
+
let entry = headers.accept !== "*/*";
|
|
63
|
+
|
|
64
|
+
// 如果文件小于10M,认为不大,直接读取
|
|
65
|
+
if (fileInfo.size < 10 * 1024 * 1024) {
|
|
66
|
+
let { source, resolveImport } = resolveImportFactory(basePath, filePath, entry, config.devServer.intercept, urlArray[1] === "download")
|
|
67
|
+
|
|
68
|
+
// 只处理非下载文件
|
|
69
|
+
// 过大的也不进行处理
|
|
70
|
+
if (urlArray[1] !== "download") {
|
|
71
|
+
for (let i = 0; i < config.module.rules.length; i++) {
|
|
72
|
+
if (config.module.rules[i].test.test(filePath)) {
|
|
73
|
+
source = config.module.rules[i].use.call({
|
|
74
|
+
root: basePath, // 服务器根路径
|
|
75
|
+
path: filePath.replace(basePath, ""), // 文件相对路径
|
|
76
|
+
entry, // 是否是浏览器地址栏直接访问
|
|
77
|
+
setFileType(_fileType) { // 设置文件类型
|
|
78
|
+
fileType = _fileType;
|
|
79
|
+
responseHeader['Content-type'] = _fileType + ";charset=utf-8";
|
|
80
|
+
}
|
|
81
|
+
}, source);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
sendType = "Read";
|
|
88
|
+
response.writeHead('200', responseHeader);
|
|
89
|
+
response.write(resolveImport(source, fileType !== "application/javascript"));
|
|
90
|
+
response.end();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 对于大文件,使用流读取
|
|
94
|
+
else {
|
|
95
|
+
sendType = "Stream";
|
|
96
|
+
responseHeader["Content-Length"] = fileInfo.size;
|
|
97
|
+
response.writeHead('200', responseHeader);
|
|
98
|
+
createReadStream(filePath).pipe(response);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log("<i> \x1b[1m\x1b[32m[OIPage-dev-server] " + sendType + " File: " + url + '\x1b[0m ' + new Date().toLocaleString());
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 否则就是404
|
|
105
|
+
else {
|
|
106
|
+
response.writeHead(404, {
|
|
107
|
+
'Content-type': "text/html;charset=utf-8",
|
|
108
|
+
'Access-Control-Allow-Origin': '*',
|
|
109
|
+
'Server': 'Powered by OIPage-dev-server@' + packageValue.version
|
|
110
|
+
});
|
|
111
|
+
response.write(resolve404(filePath, url));
|
|
112
|
+
response.end();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
Server.listen(port);
|
|
118
|
+
|
|
119
|
+
// 获取网络信息
|
|
120
|
+
let networkValue = network();
|
|
121
|
+
|
|
122
|
+
// 打印成功提示
|
|
123
|
+
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Project is running at:\x1b[0m');
|
|
124
|
+
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Loopback: \x1b[36mhttp://localhost:' + port + '/\x1b[0m');
|
|
125
|
+
for (let ipv4Item of networkValue.IPv4) console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] On Your Network (IPv4):\x1b[36m http://' + ipv4Item.address + ':' + port + '/\x1b[0m');
|
|
126
|
+
for (let ipv6Item of networkValue.IPv6) console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] On Your Network (IPv6): \x1b[36mhttp://[' + ipv6Item.address + ']:' + port + '/\x1b[0m');
|
|
127
|
+
console.log('<i> \x1b[1m\x1b[32m[OIPage-dev-server] Content not from OIPage is served from \x1b[36m"' + basePath + '" \x1b[0mdirectory');
|
|
128
|
+
console.log('\nOIPage ' + packageValue.version + ' compiled \x1b[1m\x1b[32msuccessfully\x1b[0m in ' + (new Date().valueOf() - startTime) + ' ms\n')
|
|
129
129
|
};
|