nuxt-gin-tools 0.2.13 → 0.2.15
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/README.md +16 -1
- package/package.json +1 -1
- package/src/nuxt-config.d.ts +2 -6
- package/src/nuxt-config.js +85 -16
package/README.md
CHANGED
|
@@ -88,6 +88,22 @@ Go 监听规则来自 `.go-watch.json`(见下文)。
|
|
|
88
88
|
- `killPortBeforeDevelop`: 开发前是否释放端口(默认 `true`)
|
|
89
89
|
- `cleanupBeforeDevelop`: 开发前是否执行 cleanup(默认 `false`)
|
|
90
90
|
|
|
91
|
+
### 3) 开发环境向前端暴露 `ginPort`
|
|
92
|
+
|
|
93
|
+
`createDefaultConfig` 会在 Nuxt `runtimeConfig.public` 中注入 `ginPort`:
|
|
94
|
+
|
|
95
|
+
- 开发环境:`useRuntimeConfig().public.ginPort` 为 `server.config.json` 的 `ginPort`
|
|
96
|
+
- 生产环境:`useRuntimeConfig().public.ginPort` 为 `null`
|
|
97
|
+
- 所有环境:`useRuntimeConfig().public.isDevelopment` 直接暴露当前是否开发环境
|
|
98
|
+
|
|
99
|
+
前端示例:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const config = useRuntimeConfig();
|
|
103
|
+
const ginPort = config.public.ginPort;
|
|
104
|
+
const isDevelopment = config.public.isDevelopment;
|
|
105
|
+
```
|
|
106
|
+
|
|
91
107
|
### 2) `.go-watch.json`
|
|
92
108
|
|
|
93
109
|
Go 监听配置文件,示例:
|
|
@@ -132,4 +148,3 @@ NUXT_GIN_WATCH_CONFIG=/path/to/.go-watch.json
|
|
|
132
148
|
|
|
133
149
|
- Go 侧热更新已不再依赖 Air。
|
|
134
150
|
- 当前方案为:`chokidar` 监听文件变化 + 重启 `go run main.go`。
|
|
135
|
-
|
package/package.json
CHANGED
package/src/nuxt-config.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NuxtConfig } from "nuxt/config";
|
|
2
|
-
import type
|
|
2
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
3
|
+
import type { Socket } from "node:net";
|
|
3
4
|
export interface ServerConfigJson {
|
|
4
5
|
/** 前端基础 URL */
|
|
5
6
|
baseUrl: string;
|
|
@@ -9,11 +10,6 @@ export interface ServerConfigJson {
|
|
|
9
10
|
ginPort: number;
|
|
10
11
|
}
|
|
11
12
|
export interface MyNuxtConfig {
|
|
12
|
-
/**
|
|
13
|
-
* 开发期是否将访问 Nuxt 端口(baseUrl 下的页面请求)重定向到 Gin 端口。
|
|
14
|
-
* 默认 true。
|
|
15
|
-
*/
|
|
16
|
-
redirectNuxtToGinInDev?: boolean;
|
|
17
13
|
/** 服务器配置 */
|
|
18
14
|
serverConfig: ServerConfigJson;
|
|
19
15
|
}
|
package/src/nuxt-config.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createDefaultConfig = createDefaultConfig;
|
|
4
|
+
const node_http_1 = require("node:http");
|
|
5
|
+
function isDevEnvironment() {
|
|
6
|
+
return process.env.NODE_ENV !== "production";
|
|
7
|
+
}
|
|
4
8
|
function normalizePathPrefix(value) {
|
|
5
9
|
const withLeadingSlash = value.startsWith("/") ? value : `/${value}`;
|
|
6
10
|
if (withLeadingSlash !== "/" && withLeadingSlash.endsWith("/")) {
|
|
@@ -23,11 +27,67 @@ function isBaseUrlRequest(baseUrl, requestPath) {
|
|
|
23
27
|
}
|
|
24
28
|
return requestPath === baseUrl || requestPath.startsWith(`${baseUrl}/`);
|
|
25
29
|
}
|
|
30
|
+
function forwardToGin(ginPort, req, res) {
|
|
31
|
+
var _a;
|
|
32
|
+
const proxyReq = (0, node_http_1.request)({
|
|
33
|
+
hostname: "127.0.0.1",
|
|
34
|
+
port: ginPort,
|
|
35
|
+
path: (_a = req.url) !== null && _a !== void 0 ? _a : "/",
|
|
36
|
+
method: req.method,
|
|
37
|
+
headers: Object.assign(Object.assign({}, req.headers), { host: `127.0.0.1:${ginPort}` }),
|
|
38
|
+
}, (proxyRes) => {
|
|
39
|
+
var _a;
|
|
40
|
+
res.writeHead((_a = proxyRes.statusCode) !== null && _a !== void 0 ? _a : 502, proxyRes.headers);
|
|
41
|
+
proxyRes.pipe(res);
|
|
42
|
+
});
|
|
43
|
+
proxyReq.on("error", (error) => {
|
|
44
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
+
res.statusCode = 502;
|
|
46
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
47
|
+
res.end(JSON.stringify({ error: "Bad Gateway", message }));
|
|
48
|
+
});
|
|
49
|
+
req.pipe(proxyReq);
|
|
50
|
+
}
|
|
51
|
+
function forwardWebSocketToGin(ginPort, req, clientSocket, clientHead) {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
const proxyReq = (0, node_http_1.request)({
|
|
54
|
+
hostname: "127.0.0.1",
|
|
55
|
+
port: ginPort,
|
|
56
|
+
path: (_a = req.url) !== null && _a !== void 0 ? _a : "/",
|
|
57
|
+
method: (_b = req.method) !== null && _b !== void 0 ? _b : "GET",
|
|
58
|
+
headers: Object.assign(Object.assign({}, req.headers), { host: `127.0.0.1:${ginPort}`, connection: "Upgrade" }),
|
|
59
|
+
});
|
|
60
|
+
proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
const statusLine = `HTTP/1.1 ${(_a = proxyRes.statusCode) !== null && _a !== void 0 ? _a : 101} ${(_b = proxyRes.statusMessage) !== null && _b !== void 0 ? _b : "Switching Protocols"}\r\n`;
|
|
63
|
+
const headers = proxyRes.rawHeaders;
|
|
64
|
+
let headerText = "";
|
|
65
|
+
for (let i = 0; i < headers.length; i += 2) {
|
|
66
|
+
headerText += `${headers[i]}: ${headers[i + 1]}\r\n`;
|
|
67
|
+
}
|
|
68
|
+
clientSocket.write(`${statusLine}${headerText}\r\n`);
|
|
69
|
+
if (clientHead.length > 0) {
|
|
70
|
+
proxySocket.write(clientHead);
|
|
71
|
+
}
|
|
72
|
+
if (proxyHead.length > 0) {
|
|
73
|
+
clientSocket.write(proxyHead);
|
|
74
|
+
}
|
|
75
|
+
proxySocket.pipe(clientSocket).pipe(proxySocket);
|
|
76
|
+
});
|
|
77
|
+
proxyReq.on("error", () => {
|
|
78
|
+
if (!clientSocket.destroyed) {
|
|
79
|
+
clientSocket.destroy();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
proxyReq.end();
|
|
83
|
+
}
|
|
26
84
|
/**
|
|
27
85
|
* 创建默认的 Nuxt 配置。
|
|
28
86
|
*/
|
|
29
|
-
function createDefaultConfig({ serverConfig,
|
|
87
|
+
function createDefaultConfig({ serverConfig, }) {
|
|
88
|
+
const development = isDevEnvironment();
|
|
30
89
|
const baseUrl = normalizeBaseUrl(serverConfig.baseUrl);
|
|
90
|
+
const publicGinPort = development ? serverConfig.ginPort : null;
|
|
31
91
|
return {
|
|
32
92
|
buildDir: "vue/.nuxt",
|
|
33
93
|
srcDir: "vue",
|
|
@@ -41,6 +101,14 @@ function createDefaultConfig({ serverConfig, redirectNuxtToGinInDev = true, }) {
|
|
|
41
101
|
},
|
|
42
102
|
},
|
|
43
103
|
app: { baseURL: serverConfig.baseUrl },
|
|
104
|
+
runtimeConfig: {
|
|
105
|
+
public: {
|
|
106
|
+
// Frontend can read this via useRuntimeConfig().public.ginPort in dev.
|
|
107
|
+
ginPort: publicGinPort,
|
|
108
|
+
// Frontend can use this to branch dev/prod logic directly.
|
|
109
|
+
isDevelopment: development,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
44
112
|
devServer: {
|
|
45
113
|
port: serverConfig.nuxtPort,
|
|
46
114
|
cors: {
|
|
@@ -55,27 +123,28 @@ function createDefaultConfig({ serverConfig, redirectNuxtToGinInDev = true, }) {
|
|
|
55
123
|
server: {},
|
|
56
124
|
plugins: [
|
|
57
125
|
{
|
|
58
|
-
name: "nuxt-gin-base-url-
|
|
126
|
+
name: "nuxt-gin-base-url-proxy",
|
|
59
127
|
configureServer(server) {
|
|
60
128
|
server.middlewares.use((req, res, next) => {
|
|
61
|
-
var _a
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
req.headers.accept.includes("text/html");
|
|
67
|
-
if (redirectNuxtToGinInDev === true &&
|
|
68
|
-
!isViteInternalRequest(requestPath) &&
|
|
69
|
-
isBaseUrlRequest(baseUrl, requestPath) &&
|
|
70
|
-
(method === "GET" || method === "HEAD") &&
|
|
71
|
-
acceptsHtml) {
|
|
72
|
-
res.statusCode = 307;
|
|
73
|
-
res.setHeader("Location", `http://127.0.0.1:${serverConfig.ginPort}${requestUrl}`);
|
|
74
|
-
res.end();
|
|
129
|
+
var _a;
|
|
130
|
+
const requestPath = ((_a = req.url) !== null && _a !== void 0 ? _a : "/").split("?")[0] || "/";
|
|
131
|
+
const shouldForward = !isViteInternalRequest(requestPath) && !isBaseUrlRequest(baseUrl, requestPath);
|
|
132
|
+
if (shouldForward) {
|
|
133
|
+
forwardToGin(serverConfig.ginPort, req, res);
|
|
75
134
|
return;
|
|
76
135
|
}
|
|
77
136
|
next();
|
|
78
137
|
});
|
|
138
|
+
if (server.httpServer) {
|
|
139
|
+
server.httpServer.on("upgrade", (req, socket, head) => {
|
|
140
|
+
var _a;
|
|
141
|
+
const requestPath = ((_a = req.url) !== null && _a !== void 0 ? _a : "/").split("?")[0] || "/";
|
|
142
|
+
const shouldForward = !isViteInternalRequest(requestPath) && !isBaseUrlRequest(baseUrl, requestPath);
|
|
143
|
+
if (shouldForward) {
|
|
144
|
+
forwardWebSocketToGin(serverConfig.ginPort, req, socket, head);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
79
148
|
},
|
|
80
149
|
},
|
|
81
150
|
],
|