Browse Source

调试弹窗

master
hejl 3 weeks ago
parent
commit
529e6fb652
  1. BIN
      gofaster/app/dist/renderer/img/background.7c5f6fb1.png
  2. 12
      gofaster/app/dist/renderer/index.html
  3. 20276
      gofaster/app/dist/renderer/js/chunk-vendors.js
  4. 1
      gofaster/app/dist/renderer/js/chunk-vendors.js.map
  5. 1312
      gofaster/app/dist/renderer/js/index.js
  6. 1
      gofaster/app/dist/renderer/js/index.js.map
  7. 80
      gofaster/app/package-lock.json
  8. 10
      gofaster/app/package.json
  9. 11
      gofaster/app/public/index.html
  10. 57
      gofaster/app/src/main/index.js
  11. 10
      gofaster/app/src/preload.js
  12. 35
      gofaster/app/src/public/index.html
  13. 33
      gofaster/app/src/renderer/App.vue
  14. BIN
      gofaster/app/src/renderer/assets/background.png
  15. 75
      gofaster/app/src/renderer/components/StatusBar.vue
  16. 5
      gofaster/app/src/renderer/services/db.js
  17. 91
      gofaster/app/vue.config.js

BIN
gofaster/app/dist/renderer/img/background.7c5f6fb1.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

12
gofaster/app/dist/renderer/index.html vendored

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Vue App</title>
<script defer src="js/chunk-vendors.js"></script><script defer src="js/index.js"></script></head>
<body>
<div id="app"></div>
</body>
</html>

20276
gofaster/app/dist/renderer/js/chunk-vendors.js vendored

File diff suppressed because it is too large Load Diff

1
gofaster/app/dist/renderer/js/chunk-vendors.js.map vendored

File diff suppressed because one or more lines are too long

1312
gofaster/app/dist/renderer/js/index.js vendored

File diff suppressed because it is too large Load Diff

1
gofaster/app/dist/renderer/js/index.js.map vendored

File diff suppressed because one or more lines are too long

80
gofaster/app/package-lock.json generated

@ -1,13 +1,12 @@
{ {
"name": "app", "name": "GoFaster",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "app", "name": "GoFaster",
"version": "1.0.0", "version": "1.0.0",
"hasInstallScript": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"lowdb": "^7.0.1", "lowdb": "^7.0.1",
@ -16,10 +15,13 @@
}, },
"devDependencies": { "devDependencies": {
"@electron/remote": "^2.1.3", "@electron/remote": "^2.1.3",
"@types/node": "^24.2.1",
"@vue/cli-service": "^5.0.8", "@vue/cli-service": "^5.0.8",
"concurrently": "^9.2.0", "concurrently": "^9.2.0",
"electron": "^37.2.6", "electron": "^37.2.6",
"electron-builder": "^26.0.12", "electron-builder": "^26.0.12",
"electron-reload": "^2.0.0-alpha.1",
"global": "^4.4.0",
"vue": "^3.5.18", "vue": "^3.5.18",
"wait-on": "^8.0.4" "wait-on": "^8.0.4"
} }
@ -1293,12 +1295,12 @@
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.17.1", "version": "24.2.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz", "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.2.1.tgz",
"integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==", "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.21.0" "undici-types": "~7.10.0"
} }
}, },
"node_modules/@types/node-forge": { "node_modules/@types/node-forge": {
@ -4536,6 +4538,12 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
} }
}, },
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
"dev": true
},
"node_modules/domelementtype": { "node_modules/domelementtype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@ -4842,6 +4850,15 @@
"node": ">=4.0.0" "node": ">=4.0.0"
} }
}, },
"node_modules/electron-reload": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmmirror.com/electron-reload/-/electron-reload-2.0.0-alpha.1.tgz",
"integrity": "sha512-hTde7gv0TEqxbxlB3pj2CwoyCQ9sdiQrcP8GkpzhosxyVeYM3mZbMEVKCZK3L0fED7Mz5A9IWmK7zEvi4H3P1g==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.2"
}
},
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.199", "version": "1.5.199",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz",
@ -4904,6 +4921,21 @@
"node": ">= 4.0.0" "node": ">= 4.0.0"
} }
}, },
"node_modules/electron/node_modules/@types/node": {
"version": "22.17.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.17.1.tgz",
"integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
"dev": true,
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/electron/node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true
},
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@ -5828,6 +5860,16 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true "dev": true
}, },
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dev": true,
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/global-agent": { "node_modules/global-agent": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
@ -7417,6 +7459,15 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dev": true,
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/mini-css-extract-plugin": { "node_modules/mini-css-extract-plugin": {
"version": "2.9.3", "version": "2.9.3",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.3.tgz", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.3.tgz",
@ -8992,6 +9043,15 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -10805,9 +10865,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.21.0", "version": "7.10.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.10.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
"dev": true "dev": true
}, },
"node_modules/unique-filename": { "node_modules/unique-filename": {

10
gofaster/app/package.json

@ -3,11 +3,10 @@
"version": "1.0.0", "version": "1.0.0",
"main": "src/main/index.js", "main": "src/main/index.js",
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "dev": "vue-cli-service build --mode development && electron .",
"dev:watch": "vue-cli-service build --mode development --watch & electron .",
"build": "vue-cli-service build && electron-builder", "build": "vue-cli-service build && electron-builder",
"start": "electron .", "electron:serve": "vue-cli-service build --mode development && electron ."
"dev": "concurrently \"npm run serve\" \"wait-on http://localhost:8080 && npm run start\"",
"postinstall": "electron-builder install-app-deps"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
@ -15,10 +14,13 @@
"description": "", "description": "",
"devDependencies": { "devDependencies": {
"@electron/remote": "^2.1.3", "@electron/remote": "^2.1.3",
"@types/node": "^24.2.1",
"@vue/cli-service": "^5.0.8", "@vue/cli-service": "^5.0.8",
"concurrently": "^9.2.0", "concurrently": "^9.2.0",
"electron": "^37.2.6", "electron": "^37.2.6",
"electron-builder": "^26.0.12", "electron-builder": "^26.0.12",
"electron-reload": "^2.0.0-alpha.1",
"global": "^4.4.0",
"vue": "^3.5.18", "vue": "^3.5.18",
"wait-on": "^8.0.4" "wait-on": "^8.0.4"
}, },

11
gofaster/app/public/index.html

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GoFaster</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

57
gofaster/app/src/main/index.js

@ -1,43 +1,66 @@
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path') const path = require('path')
// 获取项目根目录绝对路径
const appRoot = path.resolve(__dirname, '../..')
console.log('Application root:', appRoot)
let mainWindow let mainWindow
// 开发环境热重载
if (process.env.NODE_ENV === 'development') {
require('electron-reload')(__dirname, {
electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),
hardResetMethod: 'exit'
});
}
function createWindow() { function createWindow() {
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 1200, width: 1200,
height: 800, height: 800,
autoHideMenuBar: true,
webPreferences: { webPreferences: {
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
enableRemoteModule: false, enableRemoteModule: false,
preload: path.join(__dirname, '../preload.js') preload: path.join(appRoot, 'src/preload.js')
} }
}) })
// 开发模式下加载开发服务器 // 开发环境下抑制安全警告
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:8080') mainWindow.webContents.on('did-frame-finish-load', () => {
mainWindow.webContents.openDevTools() mainWindow.webContents.executeJavaScript(`
} else { console.warn = console.error = () => {};
mainWindow.loadFile(path.join(__dirname, '../public/index.html')) `).catch(err => console.error('抑制警告失败:', err));
});
} }
mainWindow.on('closed', () => { const loadPath = path.join(appRoot, 'dist/renderer/index.html')
mainWindow = null console.log('Loading:', loadPath)
mainWindow.loadFile(loadPath).catch(err => {
console.error('加载失败:', err)
mainWindow.loadURL(`data:text/html,<h1>加载失败: ${err.toString()}</h1>`)
}) })
mainWindow.webContents.openDevTools()
} }
app.whenReady().then(createWindow) app.whenReady().then(() => {
createWindow()
ipcMain.on('request-status', (event) => {
const statusData = { /* 你的数据 */ }
event.sender.send('status-update', statusData)
})
})
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') app.quit()
app.quit()
}
}) })
app.on('activate', () => { app.on('activate', () => {
if (mainWindow === null) { if (mainWindow === null) createWindow()
createWindow() })
}
})

10
gofaster/app/src/preload.js

@ -1,7 +1,7 @@
const { contextBridge } = require('electron') // preload.js
const { contextBridge, ipcRenderer } = require('electron')
// 安全地暴露API给渲染进程 contextBridge.exposeInMainWorld('electronAPI', {
contextBridge.exposeInMainWorld('electron', { sendStatusRequest: () => ipcRenderer.send('request-status'),
platform: process.platform onStatusUpdate: (callback) => ipcRenderer.on('status-update', callback)
// 可以添加更多安全的API
}) })

35
gofaster/app/src/public/index.html

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
<base href="./">
<!-- 强化 CSP 策略 -->
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self' ws:;
object-src 'none';
frame-src 'none';
base-uri 'self';
form-action 'none';
">
<!-- 全局 polyfill 解决方案 -->
<script>
(function() {
if (typeof global === 'undefined') {
if (typeof window !== 'undefined') window.global = window;
else if (typeof self !== 'undefined') self.global = self;
else if (typeof globalThis !== 'undefined') globalThis.global = globalThis;
}
})();
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>

33
gofaster/app/src/renderer/App.vue

@ -1,13 +1,24 @@
<!-- src/App.vue -->
<template> <template>
<div id="app"> <div id="app">
<router-view /> <router-view />
<StatusBar />
</div> </div>
</template> </template>
<script> <script>
import StatusBar from './components/StatusBar.vue';
export default { export default {
name: 'App' name: 'App',
} components: {
StatusBar
},
mounted() {
//
window.electronAPI?.sendStatusRequest();
}
};
</script> </script>
<style> <style>
@ -19,5 +30,23 @@ export default {
color: #2c3e50; color: #2c3e50;
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100vh;
width: 100vw;
/* 添加背景图片 */
background-image: url('@/assets/background.png');
/* 假设图片放在src/assets目录下 */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
/* 确保html和body元素也填满窗口 */
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
} }
</style> </style>

BIN
gofaster/app/src/renderer/assets/background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

75
gofaster/app/src/renderer/components/StatusBar.vue

@ -0,0 +1,75 @@
<!-- src/components/StatusBar.vue -->
<template>
<div class="status-bar">
<div class="status-item">服务地址: {{ serverUrl }}</div>
<div class="status-item">用户: {{ userInfo }}</div>
<div class="status-item">最近错误: {{ errorCount }}</div>
<div class="status-item">版本: {{ appVersion }}</div>
<div class="status-item">内存: {{ memoryUsage }} MB</div>
</div>
</template>
<script>
import { ref, onMounted, onUnmounted } from 'vue';
export default {
name: 'StatusBar',
setup() {
const serverUrl = ref(process.env.NODE_ENV === 'development' ? 'http://localhost:8080' : window.location.href);
const userInfo = ref('未登录');
const errorCount = ref(0);
const appVersion = ref(process.env.VUE_APP_VERSION || '1.0.0');
const memoryUsage = ref(0);
// 使
let intervalId;
onMounted(() => {
intervalId = setInterval(() => {
if (window.performance && window.performance.memory) {
memoryUsage.value = (window.performance.memory.usedJSHeapSize / (1024 * 1024)).toFixed(2);
}
}, 2000);
});
onUnmounted(() => {
clearInterval(intervalId);
});
//
window.electronAPI?.onStatusUpdate((event, data) => {
if (data.userInfo) userInfo.value = data.userInfo;
if (data.errorCount !== undefined) errorCount.value = data.errorCount;
});
return {
serverUrl,
userInfo,
errorCount,
appVersion,
memoryUsage
};
}
};
</script>
<style scoped>
.status-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 24px;
background-color: #333;
color: #fff;
display: flex;
align-items: center;
padding: 0 10px;
font-size: 12px;
border-top: 1px solid #444;
z-index: 1000;
}
.status-item {
margin-right: 20px;
}
</style>

5
gofaster/app/src/renderer/services/db.js

@ -1,4 +1,5 @@
import { Low, JSONFile } from 'lowdb' import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node' // 注意这里的变化
import { join } from 'path' import { join } from 'path'
import { app } from '@electron/remote' import { app } from '@electron/remote'
@ -6,6 +7,8 @@ const file = join(app.getPath('userData'), 'gofaster-db.json')
const adapter = new JSONFile(file) const adapter = new JSONFile(file)
const db = new Low(adapter) const db = new Low(adapter)
// 其余代码保持不变...
// 初始化数据库 // 初始化数据库
async function initDB() { async function initDB() {
await db.read() await db.read()

91
gofaster/app/vue.config.js

@ -1,55 +1,86 @@
const path = require('path') const path = require('path')
const { defineConfig } = require('@vue/cli-service') const { defineConfig } = require('@vue/cli-service')
const appRoot = path.resolve(__dirname)
module.exports = defineConfig({ module.exports = defineConfig({
outputDir: path.resolve(__dirname, 'dist/renderer'), outputDir: path.join(appRoot, 'dist/renderer'),
publicPath: './', publicPath: './',
// 关键修改:配置 Electron 构建目标和排除原生模块
configureWebpack: { configureWebpack: {
target: 'electron-renderer', // 指定为 Electron 渲染进程 target: 'electron-renderer',
externals: { node: {
electron: 'require("electron")', // 防止 Webpack 处理 electron 模块 global: false, // 禁用全局 polyfill
fs: 'require("fs")', // 排除 Node.js 原生模块 __dirname: true
path: 'require("path")',
}, },
resolve: { resolve: {
alias: { fallback: {
'@': path.resolve(__dirname, 'src/renderer'), global: false // 禁用 fallback
// 确保 Vue 单文件组件引用时自动补全扩展名 },
'views': path.resolve(__dirname, 'src/renderer/views') alias: {
}, '@': path.join(appRoot, 'src/renderer'),
// 添加扩展名自动解析 'views': path.join(appRoot, 'src/renderer/views')
extensions: ['.js', '.vue', '.json'] },
extensions: ['.js', '.vue', '.json']
},
externals: {
electron: 'require("electron")',
fs: 'require("fs")',
path: 'require("path")'
} }
}, },
// 保留原有页面配置
pages: { pages: {
index: { index: {
entry: 'src/renderer/main.js', entry: path.join(appRoot, 'src/renderer/main.js'),
template: 'public/index.html', template: path.join(appRoot, 'public/index.html'),
filename: 'index.html' filename: 'index.html'
} }
}, },
// 保留 Electron Builder 配置
pluginOptions: { pluginOptions: {
electronBuilder: { electronBuilder: {
preload: 'src/preload.js', preload: path.join(appRoot, 'src/preload.js'),
nodeIntegration: false, mainProcessFile: path.join(appRoot, 'src/main/index.js'),
contextIsolation: true, builderOptions: {
// 可选:明确指定主进程文件路径 extraResources: [{
mainProcessFile: 'src/main/index.js' from: path.join(appRoot, 'dist/renderer'),
to: 'app',
filter: ["**/*"]
}]
}
} }
}, },
// 开发服务器配置(与 Electron 主进程配合)
devServer: { devServer: {
port: 8080, // 确保与 wait-on 端口一致 hot: false,
hot: true, liveReload: false,
headers: { allowedHosts: "all",
'Access-Control-Allow-Origin': '*' static: {
} directory: path.join(__dirname, 'dist/renderer'),
watch: false
},
compress: false,
proxy: null
},
chainWebpack: config => {
// 开发环境 sourcemap
config.devtool(process.env.NODE_ENV === 'development'
? 'source-map'
: false)
// 静态资源处理
config.module
.rule('images')
.set('generator', {
filename: 'img/[name].[hash:8][ext]'
})
// 全局变量定义
config.plugin('define').tap(args => {
args[0]['global.GLOBAL'] = JSON.stringify(false)
return args
})
} }
}) })
Loading…
Cancel
Save