@quicktvui/web-cli 1.0.0-beta.37 → 1.0.0-beta.39

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/bin/qt-web-cli.js CHANGED
@@ -119,6 +119,9 @@ async function main() {
119
119
 
120
120
  // 入口候选列表
121
121
  const entryCandidates = [
122
+ { name: 'webMain (package.json)', path: pkg.webMain, type: 'web' },
123
+ { name: 'src/main-web.ts', path: './src/main-web.ts', type: 'web' },
124
+ { name: 'src/main-web.js', path: './src/main-web.js', type: 'web' },
122
125
  { name: 'src/main-native.ts', path: './src/main-native.ts', type: 'package' },
123
126
  { name: 'src/main-native.js', path: './src/main-native.js', type: 'package' },
124
127
  { name: 'src/main.ts', path: './src/main.ts', type: 'package' },
@@ -139,6 +142,8 @@ async function main() {
139
142
 
140
143
  if (!mainEntry) {
141
144
  signale.error('无法找到有效的入口文件,请检查以下路径:')
145
+ signale.error(' - package.json 中的 webMain 字段')
146
+ signale.error(' - src/main-web.ts 或 src/main-web.js')
142
147
  signale.error(' - src/main-native.ts 或 src/main-native.js')
143
148
  signale.error(' - src/main.ts 或 src/main.js')
144
149
  signale.error(' - package.json 中的 main 字段')
@@ -183,10 +188,9 @@ function startDevServer(configPath, port, shouldOpen) {
183
188
  const WebpackDevServer = require('webpack-dev-server')
184
189
  const config = require(configPath)
185
190
 
186
- // 确保 devServer 配置正确
187
191
  config.devServer = config.devServer || {}
188
192
  config.devServer.port = port
189
- config.devServer.open = false // 我们自己控制浏览器打开
193
+ config.devServer.open = false
190
194
 
191
195
  const compiler = webpack(config)
192
196
  const server = new WebpackDevServer(config.devServer, compiler)
@@ -198,14 +202,12 @@ function startDevServer(configPath, port, shouldOpen) {
198
202
  }
199
203
  signale.success(`开发服务器已启动: http://localhost:${port}`)
200
204
 
201
- // 打开浏览器
202
205
  if (shouldOpen) {
203
206
  const url = `http://localhost:${port}`
204
- openOrRefreshBrowser(url)
207
+ openBrowser(url)
205
208
  }
206
209
  })
207
210
 
208
- // 处理退出信号
209
211
  process.on('SIGINT', () => {
210
212
  server.stopCallback(() => {
211
213
  signale.info('开发服务器已停止')
@@ -251,41 +253,79 @@ function waitForServer(url, timeout = 30000) {
251
253
  }
252
254
 
253
255
  /**
254
- * 打开或刷新浏览器(支持 macOS)
256
+ * 打开浏览器
255
257
  */
256
- function openOrRefreshBrowser(url) {
258
+ function openBrowser(url) {
257
259
  const platform = process.platform
260
+ if (platform === 'darwin' && focusExistingBrowserPage(url)) {
261
+ signale.success('已切换到已打开的浏览器页面')
262
+ return
263
+ }
264
+ const command =
265
+ platform === 'darwin'
266
+ ? `open "${url}"`
267
+ : platform === 'win32'
268
+ ? `cmd /c start "" "${url}"`
269
+ : `xdg-open "${url}"`
270
+ const result = exec(command, { silent: true })
271
+
272
+ if (result.code === 0) {
273
+ signale.success('已打开浏览器')
274
+ return
275
+ }
276
+
277
+ signale.warn(`自动打开浏览器失败,请手动访问: ${url}`)
278
+ }
258
279
 
259
- if (platform === 'darwin') {
260
- // macOS: 使用 AppleScript 检查并刷新已存在的标签页
261
- const appleScript = `
280
+ function focusExistingBrowserPage(url) {
281
+ const match = /^https?:\/\/[^/]+/.exec(url)
282
+ const targetPrefix = match ? match[0] : url
283
+ const browserApps = ['Google Chrome', 'Safari', 'Arc', 'Microsoft Edge', 'Brave Browser']
284
+ const script = `
285
+ set targetPrefix to "${escapeAppleScriptString(targetPrefix)}"
286
+ set browserApps to {${browserApps.map((app) => `"${escapeAppleScriptString(app)}"`).join(', ')}}
287
+ repeat with appName in browserApps
288
+ tell application "System Events"
289
+ set isRunning to (name of processes) contains (appName as text)
290
+ end tell
291
+ if isRunning then
292
+ if (appName as text) is "Safari" then
262
293
  tell application "Safari"
263
- activate
264
- set found to false
265
294
  repeat with w in windows
266
295
  repeat with t in tabs of w
267
- if URL of t starts with "http://localhost:" then
268
- set URL of t to "${url}"
269
- set found to true
270
- exit repeat
296
+ if URL of t starts with targetPrefix then
297
+ set current tab of w to t
298
+ set index of w to 1
299
+ activate
300
+ return "FOUND"
271
301
  end if
272
302
  end repeat
273
- if found then exit repeat
274
303
  end repeat
275
- if not found then
276
- open location "${url}"
277
- end if
278
304
  end tell
279
- `
305
+ else
306
+ tell application (appName as text)
307
+ repeat with w in windows
308
+ repeat with t in tabs of w
309
+ if URL of t starts with targetPrefix then
310
+ set active tab index of w to (index of t)
311
+ set index of w to 1
312
+ activate
313
+ return "FOUND"
314
+ end if
315
+ end repeat
316
+ end repeat
317
+ end tell
318
+ end if
319
+ end if
320
+ end repeat
321
+ return "NOT_FOUND"
322
+ `.trim()
323
+ const result = exec(`osascript <<'APPLESCRIPT'\n${script}\nAPPLESCRIPT`, { silent: true })
324
+ return result.code === 0 && String(result.stdout || '').includes('FOUND')
325
+ }
280
326
 
281
- exec(`osascript -e '${appleScript.replace(/\n/g, ' ')}'`, { silent: true })
282
- signale.success('已打开/刷新浏览器')
283
- } else {
284
- // 其他平台:直接打开 URL
285
- const openCmd = platform === 'win32' ? 'start' : 'xdg-open'
286
- exec(`${openCmd} "${url}"`, { silent: true })
287
- signale.success('已打开浏览器')
288
- }
327
+ function escapeAppleScriptString(value) {
328
+ return String(value).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
289
329
  }
290
330
 
291
331
  function findProjectRoot(startDir = process.cwd()) {
@@ -10,6 +10,7 @@ const fs = require('fs')
10
10
  const projectRoot = process.env.QUICKTVUI_PROJECT_ROOT || process.cwd()
11
11
  const mainEntry = process.env.QUICKTVUI_MAIN_ENTRY || path.resolve(projectRoot, 'src/main.ts')
12
12
  const port = parseInt(process.env.QUICKTVUI_PORT || '39001', 10)
13
+ const watchPoll = parseInt(process.env.QUICKTVUI_WATCH_POLL || '1000', 10)
13
14
 
14
15
  // 尝试加载项目的 package.json
15
16
  let pkg = {}
@@ -114,7 +115,13 @@ module.exports = {
114
115
 
115
116
  devServer: {
116
117
  port,
117
- hot: true,
118
+ hot: false,
119
+ liveReload: true,
120
+ headers: {
121
+ 'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
122
+ Pragma: 'no-cache',
123
+ Expires: '0',
124
+ },
118
125
  proxy: [
119
126
  {
120
127
  context: ['/proxy'],
@@ -149,7 +156,7 @@ module.exports = {
149
156
 
150
157
  watchOptions: {
151
158
  aggregateTimeout: 1500,
152
- poll: 1000,
159
+ poll: watchPoll,
153
160
  ignored: /node_modules/,
154
161
  },
155
162
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quicktvui/web-cli",
3
- "version": "1.0.0-beta.37",
3
+ "version": "1.0.0-beta.39",
4
4
  "description": "CLI tool for QuickTVUI web development - zero configuration",
5
5
  "author": "QuickTVUI Team",
6
6
  "license": "Apache-2.0",