nuxt-gin-tools 0.1.21 → 0.2.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/.go-watch.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "tmpDir": ".build/.server",
3
+ "testDataDir": "testdata",
4
+ "includeExt": ["go", "tpl", "html"],
5
+ "includeDir": [],
6
+ "includeFile": [],
7
+ "excludeDir": [
8
+ "assets",
9
+ ".build/.server",
10
+ "vendor",
11
+ "testdata",
12
+ "node_modules",
13
+ "vue",
14
+ "api",
15
+ ".vscode",
16
+ ".git"
17
+ ],
18
+ "excludeFile": [],
19
+ "excludeRegex": ["_test.go"]
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-gin-tools",
3
- "version": "0.1.21",
3
+ "version": "0.2.0",
4
4
  "description": "This project is used as a dependency for [nuxt-gin-starter](https://github.com/RapboyGao/nuxt-gin-starter.git)",
5
5
  "bin": {
6
6
  "nuxt-gin": "index.js"
@@ -15,6 +15,7 @@
15
15
  "dependencies": {
16
16
  "7zip-min": "^2.1.0",
17
17
  "chalk": "^5.4.1",
18
+ "chokidar": "^3.6.0",
18
19
  "concurrently": "^9.2.0",
19
20
  "fast-glob": "^3.3.3",
20
21
  "fs-extra": "^11.3.0"
@@ -0,0 +1 @@
1
+ export {};
package/src/dev-go.js ADDED
@@ -0,0 +1,374 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const child_process_1 = require("child_process");
16
+ const child_process_2 = require("child_process");
17
+ const chokidar_1 = __importDefault(require("chokidar"));
18
+ const chalk_1 = __importDefault(require("chalk"));
19
+ const fs_extra_1 = require("fs-extra");
20
+ const os_1 = __importDefault(require("os"));
21
+ const path_1 = require("path");
22
+ const cwd = process.cwd();
23
+ const RESTART_DEBOUNCE_MS = 150;
24
+ const SHUTDOWN_TIMEOUT_MS = 2000;
25
+ const LOG_TAG = "go-watch";
26
+ const serverConfigPath = (0, path_1.join)(cwd, "server.config.json");
27
+ const ginPort = getGinPort();
28
+ function getGinPort() {
29
+ if (!(0, fs_extra_1.existsSync)(serverConfigPath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const serverConfig = (0, fs_extra_1.readJSONSync)(serverConfigPath);
34
+ if (Number.isInteger(serverConfig.ginPort) && serverConfig.ginPort > 0) {
35
+ return serverConfig.ginPort;
36
+ }
37
+ }
38
+ catch (_a) {
39
+ // best effort
40
+ }
41
+ return null;
42
+ }
43
+ function killPortUnix(port) {
44
+ try {
45
+ const output = (0, child_process_2.execSync)(`lsof -ti tcp:${port}`, {
46
+ stdio: ["ignore", "pipe", "ignore"],
47
+ })
48
+ .toString()
49
+ .trim();
50
+ if (!output) {
51
+ return;
52
+ }
53
+ const pids = output
54
+ .split("\n")
55
+ .map((pid) => Number(pid.trim()))
56
+ .filter((pid) => Number.isInteger(pid) && pid > 0);
57
+ for (const pid of pids) {
58
+ try {
59
+ process.kill(pid, "SIGKILL");
60
+ console.log(chalk_1.default.yellow(`[${LOG_TAG}] killed process ${pid} on ginPort ${port} (unix)`));
61
+ }
62
+ catch (_a) {
63
+ // best effort
64
+ }
65
+ }
66
+ }
67
+ catch (_b) {
68
+ // best effort
69
+ }
70
+ }
71
+ function killPortWindows(port) {
72
+ try {
73
+ const output = (0, child_process_2.execSync)(`netstat -ano -p tcp`, {
74
+ stdio: ["ignore", "pipe", "ignore"],
75
+ })
76
+ .toString()
77
+ .trim();
78
+ if (!output) {
79
+ return;
80
+ }
81
+ const pids = new Set();
82
+ for (const line of output.split("\n")) {
83
+ const trimmed = line.trim();
84
+ if (!trimmed || !trimmed.startsWith("TCP")) {
85
+ continue;
86
+ }
87
+ const parts = trimmed.split(/\s+/);
88
+ if (parts.length < 5) {
89
+ continue;
90
+ }
91
+ const localAddress = parts[1];
92
+ const pid = Number(parts[parts.length - 1]);
93
+ const match = localAddress.match(/:(\d+)$/);
94
+ if (!match) {
95
+ continue;
96
+ }
97
+ const localPort = Number(match[1]);
98
+ if (localPort === port && Number.isInteger(pid) && pid > 0) {
99
+ pids.add(pid);
100
+ }
101
+ }
102
+ for (const pid of pids) {
103
+ try {
104
+ (0, child_process_2.execSync)(`taskkill /PID ${pid} /F`, {
105
+ stdio: ["ignore", "ignore", "ignore"],
106
+ });
107
+ console.log(chalk_1.default.yellow(`[${LOG_TAG}] killed process ${pid} on ginPort ${port} (win32)`));
108
+ }
109
+ catch (_a) {
110
+ // best effort
111
+ }
112
+ }
113
+ }
114
+ catch (_b) {
115
+ // best effort
116
+ }
117
+ }
118
+ function killGinPortIfNeeded() {
119
+ if (!ginPort) {
120
+ return;
121
+ }
122
+ if (os_1.default.platform() === "win32") {
123
+ killPortWindows(ginPort);
124
+ return;
125
+ }
126
+ killPortUnix(ginPort);
127
+ }
128
+ function normalizePath(filePath) {
129
+ return filePath.replace(/\\/g, "/").replace(/^\.\//, "");
130
+ }
131
+ function toProjectRelative(filePath) {
132
+ const abs = (0, path_1.isAbsolute)(filePath) ? filePath : (0, path_1.resolve)(cwd, filePath);
133
+ return normalizePath((0, path_1.relative)(cwd, abs));
134
+ }
135
+ function toStringArray(value) {
136
+ if (!Array.isArray(value)) {
137
+ return [];
138
+ }
139
+ return value
140
+ .filter((item) => typeof item === "string")
141
+ .map((item) => item.trim())
142
+ .filter(Boolean);
143
+ }
144
+ function toStringValue(value) {
145
+ if (typeof value !== "string") {
146
+ return "";
147
+ }
148
+ return value.trim();
149
+ }
150
+ function loadWatchConfig() {
151
+ var _a, _b, _c, _d, _e, _f, _g, _h;
152
+ const defaultConfig = {
153
+ includeExt: new Set(["go"]),
154
+ includeDir: [],
155
+ includeFile: new Set(),
156
+ excludeDir: [".git", "node_modules", "vendor", "vue"],
157
+ excludeFile: new Set(),
158
+ excludeRegex: [/_test\.go$/],
159
+ tmpDir: ".build/.server",
160
+ testDataDir: "testdata",
161
+ };
162
+ const candidates = [
163
+ process.env.NUXT_GIN_WATCH_CONFIG,
164
+ (0, path_1.join)(cwd, "node_modules/nuxt-gin-tools/.go-watch.json"),
165
+ (0, path_1.join)(cwd, ".go-watch.json"),
166
+ (0, path_1.join)(__dirname, "..", ".go-watch.json"),
167
+ (0, path_1.join)(__dirname, "..", "..", ".go-watch.json"),
168
+ ].filter((item) => Boolean(item));
169
+ const configPath = candidates.find((item) => (0, fs_extra_1.existsSync)(item));
170
+ if (!configPath) {
171
+ return defaultConfig;
172
+ }
173
+ let parsedConfig = {};
174
+ try {
175
+ parsedConfig = JSON.parse((0, fs_extra_1.readFileSync)(configPath, "utf-8"));
176
+ }
177
+ catch (_j) {
178
+ console.warn(chalk_1.default.yellow(`[${LOG_TAG}] invalid watch config JSON, fallback to defaults: ${configPath}`));
179
+ return defaultConfig;
180
+ }
181
+ const includeExt = toStringArray((_a = parsedConfig.includeExt) !== null && _a !== void 0 ? _a : parsedConfig.include_ext)
182
+ .map((item) => item.replace(/^\./, ""))
183
+ .filter((item) => /^[a-zA-Z0-9]+$/.test(item));
184
+ const includeDir = toStringArray((_b = parsedConfig.includeDir) !== null && _b !== void 0 ? _b : parsedConfig.include_dir)
185
+ .map((item) => normalizePath(item))
186
+ .filter(Boolean);
187
+ const includeFile = toStringArray((_c = parsedConfig.includeFile) !== null && _c !== void 0 ? _c : parsedConfig.include_file)
188
+ .map((item) => normalizePath(item))
189
+ .filter(Boolean);
190
+ const excludeDir = toStringArray((_d = parsedConfig.excludeDir) !== null && _d !== void 0 ? _d : parsedConfig.exclude_dir)
191
+ .map((item) => normalizePath(item))
192
+ .filter(Boolean);
193
+ const excludeFile = toStringArray((_e = parsedConfig.excludeFile) !== null && _e !== void 0 ? _e : parsedConfig.exclude_file)
194
+ .map((item) => normalizePath(item))
195
+ .filter(Boolean);
196
+ const excludeRegex = toStringArray((_f = parsedConfig.excludeRegex) !== null && _f !== void 0 ? _f : parsedConfig.exclude_regex)
197
+ .map((item) => {
198
+ try {
199
+ return new RegExp(item);
200
+ }
201
+ catch (_a) {
202
+ return null;
203
+ }
204
+ })
205
+ .filter((item) => item instanceof RegExp);
206
+ const tmpDir = normalizePath(toStringValue((_g = parsedConfig.tmpDir) !== null && _g !== void 0 ? _g : parsedConfig.tmp_dir) || defaultConfig.tmpDir);
207
+ const testdataDir = normalizePath(toStringValue((_h = parsedConfig.testDataDir) !== null && _h !== void 0 ? _h : parsedConfig.testdata_dir) ||
208
+ defaultConfig.testDataDir);
209
+ return {
210
+ includeExt: new Set(includeExt.length ? includeExt : [...defaultConfig.includeExt]),
211
+ includeDir,
212
+ includeFile: new Set(includeFile),
213
+ excludeDir: [...new Set([...defaultConfig.excludeDir, ...excludeDir, tmpDir, testdataDir])],
214
+ excludeFile: new Set(excludeFile),
215
+ excludeRegex: excludeRegex.length ? excludeRegex : defaultConfig.excludeRegex,
216
+ tmpDir,
217
+ testDataDir: testdataDir,
218
+ };
219
+ }
220
+ function pathInDir(relPath, dir) {
221
+ const normalizedDir = normalizePath(dir).replace(/\/+$/, "");
222
+ return relPath === normalizedDir || relPath.startsWith(`${normalizedDir}/`);
223
+ }
224
+ function shouldIgnore(relPath, config) {
225
+ if (!relPath || relPath === ".") {
226
+ return false;
227
+ }
228
+ if (config.excludeFile.has(relPath)) {
229
+ return true;
230
+ }
231
+ if (config.excludeDir.some((dir) => pathInDir(relPath, dir))) {
232
+ return true;
233
+ }
234
+ return config.excludeRegex.some((reg) => reg.test(relPath));
235
+ }
236
+ function shouldTrigger(relPath, config) {
237
+ if (shouldIgnore(relPath, config)) {
238
+ return false;
239
+ }
240
+ const ext = (0, path_1.extname)(relPath).replace(/^\./, "");
241
+ const inIncludedFile = config.includeFile.has(relPath);
242
+ if (config.includeDir.length > 0) {
243
+ const inIncludedDir = config.includeDir.some((dir) => pathInDir(relPath, dir));
244
+ if (!inIncludedDir && !inIncludedFile) {
245
+ return false;
246
+ }
247
+ }
248
+ if (inIncludedFile) {
249
+ return true;
250
+ }
251
+ if (!ext) {
252
+ return false;
253
+ }
254
+ return config.includeExt.has(ext);
255
+ }
256
+ function quote(arg) {
257
+ if (/\s/.test(arg)) {
258
+ return `"${arg.replace(/"/g, '\\"')}"`;
259
+ }
260
+ return arg;
261
+ }
262
+ function runGoProcess() {
263
+ const command = `go run ${quote("main.go")}`;
264
+ killGinPortIfNeeded();
265
+ console.log(chalk_1.default.green(`[${LOG_TAG}] start: ${command}`));
266
+ return (0, child_process_1.spawn)(command, {
267
+ cwd,
268
+ shell: true,
269
+ stdio: "inherit",
270
+ });
271
+ }
272
+ function stopGoProcess(proc) {
273
+ return __awaiter(this, void 0, void 0, function* () {
274
+ if (!proc || proc.killed || proc.exitCode !== null) {
275
+ return;
276
+ }
277
+ yield new Promise((resolveStop) => {
278
+ let finished = false;
279
+ const done = () => {
280
+ if (finished) {
281
+ return;
282
+ }
283
+ finished = true;
284
+ resolveStop();
285
+ };
286
+ const timer = setTimeout(() => {
287
+ try {
288
+ proc.kill("SIGKILL");
289
+ }
290
+ catch (_a) {
291
+ // best effort
292
+ }
293
+ done();
294
+ }, SHUTDOWN_TIMEOUT_MS);
295
+ proc.once("exit", () => {
296
+ clearTimeout(timer);
297
+ done();
298
+ });
299
+ try {
300
+ proc.kill("SIGTERM");
301
+ }
302
+ catch (_a) {
303
+ clearTimeout(timer);
304
+ done();
305
+ }
306
+ });
307
+ });
308
+ }
309
+ function start() {
310
+ return __awaiter(this, void 0, void 0, function* () {
311
+ const watchConfig = loadWatchConfig();
312
+ const watchRoots = watchConfig.includeDir.length
313
+ ? watchConfig.includeDir.map((dir) => (0, path_1.join)(cwd, dir))
314
+ : [cwd];
315
+ console.log(chalk_1.default.cyan(`[${LOG_TAG}] watching: ${watchRoots.map((item) => toProjectRelative(item)).join(", ")}`));
316
+ let restarting = false;
317
+ let goProc = runGoProcess();
318
+ let restartTimer = null;
319
+ const watcher = chokidar_1.default.watch(watchRoots, {
320
+ ignoreInitial: true,
321
+ ignored: (pathName) => shouldIgnore(toProjectRelative(pathName), watchConfig),
322
+ awaitWriteFinish: {
323
+ stabilityThreshold: 120,
324
+ pollInterval: 20,
325
+ },
326
+ });
327
+ const triggerRestart = (eventName, changedPath) => {
328
+ const relPath = toProjectRelative(changedPath);
329
+ if (!shouldTrigger(relPath, watchConfig)) {
330
+ return;
331
+ }
332
+ if (restartTimer) {
333
+ clearTimeout(restartTimer);
334
+ }
335
+ restartTimer = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
336
+ if (restarting) {
337
+ return;
338
+ }
339
+ restarting = true;
340
+ console.log(chalk_1.default.yellow(`[${LOG_TAG}] ${eventName}: ${relPath}, restarting...`));
341
+ yield stopGoProcess(goProc);
342
+ goProc = runGoProcess();
343
+ restarting = false;
344
+ }), RESTART_DEBOUNCE_MS);
345
+ };
346
+ watcher
347
+ .on("add", (filePath) => triggerRestart("add", filePath))
348
+ .on("change", (filePath) => triggerRestart("change", filePath))
349
+ .on("unlink", (filePath) => triggerRestart("unlink", filePath))
350
+ .on("error", (error) => {
351
+ console.error(chalk_1.default.red(`[${LOG_TAG}] watcher error: ${String(error)}`));
352
+ });
353
+ const shutdown = () => __awaiter(this, void 0, void 0, function* () {
354
+ if (restartTimer) {
355
+ clearTimeout(restartTimer);
356
+ restartTimer = null;
357
+ }
358
+ yield watcher.close();
359
+ yield stopGoProcess(goProc);
360
+ });
361
+ process.on("SIGINT", () => __awaiter(this, void 0, void 0, function* () {
362
+ yield shutdown();
363
+ process.exit(0);
364
+ }));
365
+ process.on("SIGTERM", () => __awaiter(this, void 0, void 0, function* () {
366
+ yield shutdown();
367
+ process.exit(0);
368
+ }));
369
+ });
370
+ }
371
+ start().catch((error) => {
372
+ console.error(chalk_1.default.red(`[${LOG_TAG}] failed to start: ${String(error)}`));
373
+ process.exit(1);
374
+ });
package/src/develop.js CHANGED
@@ -17,37 +17,134 @@ const concurrently_1 = __importDefault(require("concurrently"));
17
17
  const fs_extra_1 = require("fs-extra");
18
18
  const os_1 = __importDefault(require("os"));
19
19
  const path_1 = require("path");
20
+ const child_process_1 = require("child_process");
21
+ const chalk_1 = __importDefault(require("chalk"));
20
22
  const cleanup_1 = __importDefault(require("./cleanup"));
21
23
  const postinstall_1 = __importDefault(require("./postinstall"));
22
24
  const cwd = process.cwd();
23
25
  const serverConfig = (0, fs_extra_1.readJSONSync)((0, path_1.join)(cwd, "server.config.json"));
24
- /**
25
- *
26
- * @returns {string} 返回air命令的路径
27
- * 根据操作系统不同,返回不同的路径
28
- * 如果是macOS,返回~/go/bin/air
29
- * 如果是其他操作系统,返回air
30
- */
31
- function getAirCommand() {
32
- if (os_1.default.platform() === "darwin") {
33
- return "~/go/bin/air -c node_modules/nuxt-gin-tools/.air.toml";
26
+ function getGoDevCommand() {
27
+ const scriptPath = (0, path_1.join)(__dirname, "dev-go.js");
28
+ return `"${process.execPath}" "${scriptPath}"`;
29
+ }
30
+ function killPort(port) {
31
+ if (!Number.isInteger(port)) {
32
+ return;
34
33
  }
35
- else {
36
- return "air -c node_modules/nuxt-gin-tools/.air.toml";
34
+ try {
35
+ const output = (0, child_process_1.execSync)(`lsof -ti tcp:${port}`, {
36
+ stdio: ["ignore", "pipe", "ignore"],
37
+ })
38
+ .toString()
39
+ .trim();
40
+ if (!output) {
41
+ return;
42
+ }
43
+ const pids = output
44
+ .split("\n")
45
+ .map((pid) => Number(pid.trim()))
46
+ .filter((pid) => Number.isInteger(pid) && pid > 0);
47
+ for (const pid of pids) {
48
+ try {
49
+ process.kill(pid, "SIGKILL");
50
+ console.log(chalk_1.default.yellow(`Killed process ${pid} on port ${port} (unix)`));
51
+ }
52
+ catch (_a) {
53
+ // Best-effort: if the process is already gone, ignore.
54
+ }
55
+ }
56
+ }
57
+ catch (_b) {
58
+ // Best-effort: lsof might be missing or no process is listening on the port.
59
+ }
60
+ }
61
+ function killPortWindows(port) {
62
+ if (!Number.isInteger(port)) {
63
+ return;
64
+ }
65
+ try {
66
+ const output = (0, child_process_1.execSync)(`netstat -ano -p tcp`, {
67
+ stdio: ["ignore", "pipe", "ignore"],
68
+ })
69
+ .toString()
70
+ .trim();
71
+ if (!output) {
72
+ return;
73
+ }
74
+ const pids = new Set();
75
+ for (const line of output.split("\n")) {
76
+ const trimmed = line.trim();
77
+ if (!trimmed || !trimmed.startsWith("TCP")) {
78
+ continue;
79
+ }
80
+ const parts = trimmed.split(/\s+/);
81
+ if (parts.length < 5) {
82
+ continue;
83
+ }
84
+ const localAddress = parts[1];
85
+ const pid = Number(parts[parts.length - 1]);
86
+ const match = localAddress.match(/:(\d+)$/);
87
+ if (!match) {
88
+ continue;
89
+ }
90
+ const localPort = Number(match[1]);
91
+ if (localPort === port && Number.isInteger(pid) && pid > 0) {
92
+ pids.add(pid);
93
+ }
94
+ }
95
+ for (const pid of pids) {
96
+ try {
97
+ (0, child_process_1.execSync)(`taskkill /PID ${pid} /F`, {
98
+ stdio: ["ignore", "ignore", "ignore"],
99
+ });
100
+ console.log(chalk_1.default.yellow(`Killed process ${pid} on port ${port} (win32)`));
101
+ }
102
+ catch (_a) {
103
+ // Best-effort: if the process is already gone, ignore.
104
+ }
105
+ }
106
+ }
107
+ catch (_b) {
108
+ // Best-effort: netstat might be missing or no process is listening on the port.
109
+ }
110
+ }
111
+ function killPortsFromConfig() {
112
+ const ports = [serverConfig.ginPort, serverConfig.nuxtPort]
113
+ .filter((port) => Number.isInteger(port) && port > 0)
114
+ .filter((port, index, list) => list.indexOf(port) === index);
115
+ for (const port of ports) {
116
+ if (os_1.default.platform() === "win32") {
117
+ killPortWindows(port);
118
+ }
119
+ else {
120
+ killPort(port);
121
+ }
37
122
  }
38
123
  }
39
124
  function develop() {
40
125
  return __awaiter(this, void 0, void 0, function* () {
41
- // 如果不存在 .nuxt 目录或 go.sum 文件,则执行清理和安装后处理
42
- // 这可以确保开发环境干净且依赖正确
43
- if (!(0, fs_extra_1.existsSync)((0, path_1.join)(cwd, "vue/.nuxt")) || !(0, fs_extra_1.existsSync)((0, path_1.join)(cwd, "go.sum"))) {
126
+ const cleanupBeforeDevelop = serverConfig.cleanupBeforeDevelop === true;
127
+ const killPortBeforeDevelop = serverConfig.killPortBeforeDevelop !== false;
128
+ // 如果配置为开发前清理,则直接执行清理和安装后处理
129
+ if (cleanupBeforeDevelop) {
44
130
  yield (0, cleanup_1.default)();
45
131
  yield (0, postinstall_1.default)();
46
132
  }
133
+ else {
134
+ // 否则仅在关键依赖缺失时执行
135
+ if (!(0, fs_extra_1.existsSync)((0, path_1.join)(cwd, "vue/.nuxt")) || !(0, fs_extra_1.existsSync)((0, path_1.join)(cwd, "go.sum"))) {
136
+ yield (0, cleanup_1.default)();
137
+ yield (0, postinstall_1.default)();
138
+ }
139
+ }
140
+ // 在开发前确保占用端口被释放
141
+ if (killPortBeforeDevelop) {
142
+ killPortsFromConfig();
143
+ }
47
144
  (0, fs_extra_1.ensureDirSync)((0, path_1.join)(cwd, ".build/.server"));
48
145
  yield (0, concurrently_1.default)([
49
146
  {
50
- command: getAirCommand(),
147
+ command: getGoDevCommand(),
51
148
  name: "go",
52
149
  prefixColor: "green",
53
150
  },
@@ -9,7 +9,6 @@ const node_child_process_1 = require("node:child_process");
9
9
  function postInstall() {
10
10
  const hasGo = (0, node_child_process_1.spawnSync)("go", ["version"], { stdio: "ignore", shell: true }).status ===
11
11
  0;
12
- const hasAir = (0, node_child_process_1.spawnSync)("air", ["-v"], { stdio: "ignore", shell: true }).status === 0;
13
12
  const commands = [
14
13
  {
15
14
  command: "npx nuxt prepare",
@@ -27,21 +26,6 @@ function postInstall() {
27
26
  else {
28
27
  console.warn("[nuxt-gin-tools] 未检测到 Go,已跳过 Go 相关安装。请先安装 Go 后再重新运行相关命令。");
29
28
  }
30
- if (!hasAir) {
31
- const isWindows = process.platform === "win32";
32
- const pathHint = isWindows
33
- ? [
34
- "PowerShell: $env:Path += \";$env:USERPROFILE\\go\\bin\"",
35
- "CMD: set PATH=%PATH%;%USERPROFILE%\\go\\bin",
36
- ].join(" | ")
37
- : "export PATH=\"$PATH:$HOME/go/bin\"";
38
- console.warn([
39
- "[nuxt-gin-tools] 未检测到 air,请先安装 1.63.0 版本并加入 PATH。",
40
- "安装命令: go install github.com/cosmtrek/air@v1.63.0",
41
- `PATH 示例: ${pathHint}`,
42
- "安装完成后请执行: air -v",
43
- ].join("\n"));
44
- }
45
29
  // 执行并发命令
46
30
  return (0, concurrently_1.default)(commands).result;
47
31
  }
@@ -15,6 +15,16 @@
15
15
  "title": "The base url for nuxt. / Nuxt的BaseUrl",
16
16
  "type": "string",
17
17
  "pattern": "^\\/\\w.+"
18
+ },
19
+ "killPortBeforeDevelop": {
20
+ "title": "Kill port before develop / 开发前释放端口",
21
+ "type": "boolean",
22
+ "default": true
23
+ },
24
+ "cleanupBeforeDevelop": {
25
+ "title": "Cleanup before develop / 开发前清理",
26
+ "type": "boolean",
27
+ "default": false
18
28
  }
19
29
  },
20
30
  "required": [
@@ -22,4 +32,4 @@
22
32
  "nuxtPort",
23
33
  "baseUrl"
24
34
  ]
25
- }
35
+ }
package/.air.toml DELETED
@@ -1,42 +0,0 @@
1
- root = "."
2
- testdata_dir = "testdata"
3
- tmp_dir= ".build/.server"
4
-
5
- [build]
6
- args_bin = []
7
- bin = "./.build/.server/development.exe"
8
- cmd = "go build -o ./.build/.server/development.exe ."
9
- delay = 0
10
- exclude_dir = ["assets", ".build/.server", "vendor", "testdata", "node_modules", "vue", "api", ".vscode", ".git"]
11
- exclude_file = []
12
- exclude_regex = ["_test.go"]
13
- exclude_unchanged = false
14
- follow_symlink = false
15
- full_bin = ""
16
- include_dir = []
17
- include_ext = ["go", "tpl", ".build/.server", "html"]
18
- include_file = []
19
- kill_delay = "0s"
20
- log = "build-errors.log"
21
- rerun = false
22
- rerun_delay = 500
23
- send_interrupt = false
24
- stop_on_error = false
25
-
26
- [color]
27
- app = ""
28
- build = "yellow"
29
- main = "magenta"
30
- runner = "green"
31
- watcher = "cyan"
32
-
33
- [log]
34
- main_only = false
35
- time = true
36
-
37
- [misc]
38
- clean_on_exit = false
39
-
40
- [screen]
41
- clear_on_rebuild = false
42
- keep_scroll = true