fix bugs
This commit is contained in:
206
H5部署说明.md
Normal file
206
H5部署说明.md
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# H5 版本部署说明
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
编译后的 H5 版本在服务器上显示样式丢失(乱码),但文字内容正常显示。
|
||||||
|
|
||||||
|
## 原因分析
|
||||||
|
1. **静态资源路径问题**:CSS 和 JS 文件路径不正确
|
||||||
|
2. **服务器配置问题**:Nginx 或 Apache 配置不正确
|
||||||
|
3. **MIME 类型问题**:CSS 文件被当作文本文件加载
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 方案1:检查文件结构(推荐)
|
||||||
|
|
||||||
|
编译后的文件结构应该是:
|
||||||
|
```
|
||||||
|
dist/build/h5/
|
||||||
|
├── index.html
|
||||||
|
└── static/
|
||||||
|
├── index.css
|
||||||
|
└── js/
|
||||||
|
├── chunk-vendors.xxx.js
|
||||||
|
└── index.xxx.js
|
||||||
|
```
|
||||||
|
|
||||||
|
**部署步骤:**
|
||||||
|
1. 将整个 `dist/build/h5` 目录上传到服务器
|
||||||
|
2. 确保目录结构完整,不要只上传 `index.html`
|
||||||
|
3. 访问 `http://your-domain/index.html`
|
||||||
|
|
||||||
|
### 方案2:Nginx 配置
|
||||||
|
|
||||||
|
如果使用 Nginx,确保配置正确:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
# 根目录指向 h5 目录
|
||||||
|
root /path/to/dist/build/h5;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# 确保静态资源正确加载
|
||||||
|
location /static/ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# SPA 路由支持
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 确保 CSS 文件 MIME 类型正确
|
||||||
|
location ~* \.css$ {
|
||||||
|
add_header Content-Type text/css;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 确保 JS 文件 MIME 类型正确
|
||||||
|
location ~* \.js$ {
|
||||||
|
add_header Content-Type application/javascript;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案3:Apache 配置
|
||||||
|
|
||||||
|
如果使用 Apache,在 `h5` 目录下创建 `.htaccess` 文件:
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteBase /
|
||||||
|
RewriteRule ^index\.html$ - [L]
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule . /index.html [L]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# 设置正确的 MIME 类型
|
||||||
|
<IfModule mod_mime.c>
|
||||||
|
AddType text/css .css
|
||||||
|
AddType application/javascript .js
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# 启用 Gzip 压缩
|
||||||
|
<IfModule mod_deflate.c>
|
||||||
|
AddOutputFilterByType DEFLATE text/html text/css application/javascript
|
||||||
|
</IfModule>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案4:修改 publicPath(如果部署在子目录)
|
||||||
|
|
||||||
|
如果部署在子目录(如 `http://your-domain.com/martial/`),需要修改 `vue.config.js`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
module.exports = {
|
||||||
|
// 修改为子目录路径
|
||||||
|
publicPath: process.env.NODE_ENV === 'production' ? '/martial/' : '/',
|
||||||
|
|
||||||
|
// 其他配置...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
然后重新编译:
|
||||||
|
```bash
|
||||||
|
npm run build:h5
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案5:检查浏览器控制台
|
||||||
|
|
||||||
|
打开浏览器开发者工具(F12),查看:
|
||||||
|
|
||||||
|
1. **Network 标签页**
|
||||||
|
- 检查 CSS 文件是否加载成功(状态码应该是 200)
|
||||||
|
- 检查文件路径是否正确
|
||||||
|
- 检查 Content-Type 是否为 `text/css`
|
||||||
|
|
||||||
|
2. **Console 标签页**
|
||||||
|
- 查看是否有 404 错误
|
||||||
|
- 查看是否有 CORS 错误
|
||||||
|
|
||||||
|
3. **常见错误信息:**
|
||||||
|
```
|
||||||
|
Failed to load resource: net::ERR_FILE_NOT_FOUND
|
||||||
|
→ 文件路径不正确,检查 publicPath 配置
|
||||||
|
|
||||||
|
Refused to apply style from '...' because its MIME type ('text/html') is not a supported stylesheet MIME type
|
||||||
|
→ CSS 文件被当作 HTML 加载,检查服务器配置
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速诊断步骤
|
||||||
|
|
||||||
|
1. **本地测试**
|
||||||
|
```bash
|
||||||
|
# 在 dist/build/h5 目录下启动本地服务器
|
||||||
|
cd dist/build/h5
|
||||||
|
python -m http.server 8000
|
||||||
|
# 或使用 Node.js
|
||||||
|
npx http-server -p 8000
|
||||||
|
```
|
||||||
|
访问 `http://localhost:8000`,如果本地正常,说明是服务器配置问题。
|
||||||
|
|
||||||
|
2. **检查文件是否上传完整**
|
||||||
|
```bash
|
||||||
|
# 在服务器上检查文件
|
||||||
|
ls -la /path/to/h5/static/
|
||||||
|
# 应该看到 index.css 和 js 目录
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查文件权限**
|
||||||
|
```bash
|
||||||
|
# 确保文件可读
|
||||||
|
chmod -R 755 /path/to/h5/
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **检查 CSS 文件内容**
|
||||||
|
```bash
|
||||||
|
# 查看 CSS 文件前几行
|
||||||
|
head -n 20 /path/to/h5/static/index.css
|
||||||
|
# 应该看到 CSS 代码,而不是 HTML 或错误信息
|
||||||
|
```
|
||||||
|
|
||||||
|
## 重新编译
|
||||||
|
|
||||||
|
如果修改了配置,需要重新编译:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 清理旧的编译文件
|
||||||
|
rm -rf dist/build/h5
|
||||||
|
|
||||||
|
# 重新编译
|
||||||
|
npm run build:h5
|
||||||
|
|
||||||
|
# 检查编译结果
|
||||||
|
ls -la dist/build/h5/static/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q1: 样式完全丢失,只显示纯文本
|
||||||
|
**A:** CSS 文件没有加载,检查:
|
||||||
|
- 文件路径是否正确
|
||||||
|
- 服务器配置是否正确
|
||||||
|
- MIME 类型是否正确
|
||||||
|
|
||||||
|
### Q2: 部分样式丢失
|
||||||
|
**A:** CSS 文件加载了但不完整,检查:
|
||||||
|
- CSS 文件是否完整上传
|
||||||
|
- 是否有 CSS 压缩错误
|
||||||
|
- 浏览器兼容性问题
|
||||||
|
|
||||||
|
### Q3: 本地正常,服务器异常
|
||||||
|
**A:** 服务器配置问题,检查:
|
||||||
|
- publicPath 配置
|
||||||
|
- Nginx/Apache 配置
|
||||||
|
- 文件权限
|
||||||
|
|
||||||
|
## 联系支持
|
||||||
|
|
||||||
|
如果以上方案都无法解决问题,请提供:
|
||||||
|
1. 浏览器控制台截图(Network 和 Console)
|
||||||
|
2. 服务器配置文件
|
||||||
|
3. 部署的完整路径
|
||||||
|
4. 访问的 URL
|
||||||
223
test-h5.html
Normal file
223
test-h5.html
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>H5 部署测试</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 50px auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.test-card {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.test-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1B7C5E;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.test-result {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
background-color: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
border: 1px solid #c3e6cb;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
background-color: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
border: 1px solid #f5c6cb;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
background-color: #d1ecf1;
|
||||||
|
color: #0c5460;
|
||||||
|
border: 1px solid #bee5eb;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #1B7C5E;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #156650;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>武术评分系统 H5 部署测试</h1>
|
||||||
|
|
||||||
|
<div class="test-card">
|
||||||
|
<div class="test-title">1. 当前页面信息</div>
|
||||||
|
<div id="pageInfo"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-card">
|
||||||
|
<div class="test-title">2. 静态资源测试</div>
|
||||||
|
<button onclick="testResources()">测试资源加载</button>
|
||||||
|
<div id="resourceTest"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-card">
|
||||||
|
<div class="test-title">3. 路径配置检查</div>
|
||||||
|
<div id="pathCheck"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-card">
|
||||||
|
<div class="test-title">4. 解决方案</div>
|
||||||
|
<div id="solutions"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 显示页面信息
|
||||||
|
function showPageInfo() {
|
||||||
|
const info = {
|
||||||
|
'URL': window.location.href,
|
||||||
|
'协议': window.location.protocol,
|
||||||
|
'主机': window.location.host,
|
||||||
|
'路径': window.location.pathname,
|
||||||
|
'基础路径': document.baseURI
|
||||||
|
};
|
||||||
|
|
||||||
|
let html = '<div class="test-result info">';
|
||||||
|
for (let key in info) {
|
||||||
|
html += `<strong>${key}:</strong> ${info[key]}<br>`;
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
document.getElementById('pageInfo').innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试资源加载
|
||||||
|
async function testResources() {
|
||||||
|
const resultDiv = document.getElementById('resourceTest');
|
||||||
|
resultDiv.innerHTML = '<div class="test-result info">正在测试...</div>';
|
||||||
|
|
||||||
|
const resources = [
|
||||||
|
'./static/index.css',
|
||||||
|
'./static/js/chunk-vendors.js',
|
||||||
|
'./static/js/index.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
let html = '';
|
||||||
|
let allSuccess = true;
|
||||||
|
|
||||||
|
for (let resource of resources) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(resource, { method: 'HEAD' });
|
||||||
|
const contentType = response.headers.get('Content-Type');
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
html += `<div class="test-result success">
|
||||||
|
✓ ${resource}<br>
|
||||||
|
状态: ${response.status}<br>
|
||||||
|
类型: ${contentType}
|
||||||
|
</div>`;
|
||||||
|
} else {
|
||||||
|
html += `<div class="test-result error">
|
||||||
|
✗ ${resource}<br>
|
||||||
|
状态: ${response.status} ${response.statusText}
|
||||||
|
</div>`;
|
||||||
|
allSuccess = false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
html += `<div class="test-result error">
|
||||||
|
✗ ${resource}<br>
|
||||||
|
错误: ${error.message}
|
||||||
|
</div>`;
|
||||||
|
allSuccess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allSuccess) {
|
||||||
|
html += '<div class="test-result success"><strong>所有资源加载正常!</strong></div>';
|
||||||
|
} else {
|
||||||
|
html += '<div class="test-result error"><strong>部分资源加载失败,请检查文件路径和服务器配置</strong></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
resultDiv.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查路径配置
|
||||||
|
function checkPaths() {
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
const isSubDir = currentPath.includes('/') && currentPath !== '/';
|
||||||
|
|
||||||
|
let html = '<div class="test-result info">';
|
||||||
|
html += `<strong>当前路径:</strong> ${currentPath}<br>`;
|
||||||
|
html += `<strong>是否在子目录:</strong> ${isSubDir ? '是' : '否'}<br>`;
|
||||||
|
|
||||||
|
if (isSubDir) {
|
||||||
|
html += '<br><strong>⚠️ 检测到部署在子目录</strong><br>';
|
||||||
|
html += '需要修改 vue.config.js 中的 publicPath 配置';
|
||||||
|
} else {
|
||||||
|
html += '<br><strong>✓ 部署在根目录</strong>';
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
document.getElementById('pathCheck').innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示解决方案
|
||||||
|
function showSolutions() {
|
||||||
|
const html = `
|
||||||
|
<div class="test-result info">
|
||||||
|
<strong>常见问题解决方案:</strong><br><br>
|
||||||
|
|
||||||
|
<strong>1. 样式完全丢失</strong><br>
|
||||||
|
• 检查 static/index.css 文件是否存在<br>
|
||||||
|
• 检查服务器 MIME 类型配置<br>
|
||||||
|
• 打开浏览器控制台查看 Network 标签<br><br>
|
||||||
|
|
||||||
|
<strong>2. 部署在子目录</strong><br>
|
||||||
|
• 修改 vue.config.js 的 publicPath<br>
|
||||||
|
• 重新编译: npm run build:h5<br><br>
|
||||||
|
|
||||||
|
<strong>3. Nginx 配置</strong><br>
|
||||||
|
<pre>location /static/ {
|
||||||
|
expires 30d;
|
||||||
|
}
|
||||||
|
location ~* \\.css$ {
|
||||||
|
add_header Content-Type text/css;
|
||||||
|
}</pre><br>
|
||||||
|
|
||||||
|
<strong>4. 本地测试</strong><br>
|
||||||
|
• cd dist/build/h5<br>
|
||||||
|
• python -m http.server 8000<br>
|
||||||
|
• 访问 http://localhost:8000<br>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById('solutions').innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时执行
|
||||||
|
window.onload = function() {
|
||||||
|
showPageInfo();
|
||||||
|
checkPaths();
|
||||||
|
showSolutions();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -5,12 +5,26 @@ module.exports = {
|
|||||||
// 静态资源目录
|
// 静态资源目录
|
||||||
assetsDir: 'static',
|
assetsDir: 'static',
|
||||||
|
|
||||||
|
// 公共路径 - 重要!确保静态资源能正确加载
|
||||||
|
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
|
||||||
|
|
||||||
// 生产环境配置
|
// 生产环境配置
|
||||||
productionSourceMap: false,
|
productionSourceMap: false,
|
||||||
|
|
||||||
// CSS 提取配置
|
// CSS 提取配置
|
||||||
css: {
|
css: {
|
||||||
extract: true
|
extract: true,
|
||||||
|
sourceMap: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// 开发服务器配置
|
||||||
|
devServer: {
|
||||||
|
port: 8080,
|
||||||
|
open: true,
|
||||||
|
overlay: {
|
||||||
|
warnings: false,
|
||||||
|
errors: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
chainWebpack: config => {
|
chainWebpack: config => {
|
||||||
@@ -18,5 +32,13 @@ module.exports = {
|
|||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
config.performance.hints(false)
|
config.performance.hints(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 确保 CSS 文件正确处理
|
||||||
|
config.module
|
||||||
|
.rule('vue')
|
||||||
|
.use('vue-loader')
|
||||||
|
.tap(options => {
|
||||||
|
return options
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user