uniapp基础(五)调试与错误

目录

一、编译错误的常见类型及解决方法

[1. 依赖冲突或缺失](#1. 依赖冲突或缺失)

[2. 语法错误](#2. 语法错误)

[3. 路径引用错误](#3. 路径引用错误)

[4. 平台特有代码未适配](#4. 平台特有代码未适配)

[5. 组件注册失败](#5. 组件注册失败)

[6. 分包配置错误](#6. 分包配置错误)

[7. 原生插件集成问题](#7. 原生插件集成问题)

[8.manifest.json 格式错误](#8.manifest.json 格式错误)

[9. pages.json 路由配置错误](#9. pages.json 路由配置错误)

[10. 内存不足](#10. 内存不足)

错误日志:

常见触发场景

排查方法

解决方案优化

进阶调试技巧

11.网络请求错误

(1).跨域问题

(2).404接口路径错误

(3).400参数格式错误

(4).500服务器端错误

(6).网络连接问题

UniApp中的网络请求示例

错误处理建议

[12. TypeScript 类型错误](#12. TypeScript 类型错误)

(1).类型不匹配错误

(2).缺少必要属性

(3).函数参数类型不匹配

(4).未识别的属性

错误排查通用步骤

二、处理跨域问题的方法?

1.配置本地开发服务器代理

[2.使用后端设置 CORS 头](#2.使用后端设置 CORS 头)

[3.使用 JSONP 请求](#3.使用 JSONP 请求)

4.使用云函数中转请求

[5.生产环境使用 Nginx 反向代理](#5.生产环境使用 Nginx 反向代理)

注意事项

三、如何捕获并处理全局错误?

[1.使用 onError 生命周期钩子](#1.使用 onError 生命周期钩子)

[2.监听 UnhandledRejection(Promise 错误)](#2.监听 UnhandledRejection(Promise 错误))

3.封装请求拦截器

错误处理的最佳实践

注意事项

四、小程序白屏

检查网络连接

优化代码包体积

预加载关键资源

启用骨架屏

检查页面路由堆栈

监控异常并上报

兼容性处理

内存管理优化


一、编译错误的常见类型及解决方法

1. 依赖冲突或缺失

错误日志:

javascript 复制代码
npm ERR! conflict 或 Version mismatch。
Module not found: Error: Can't resolve 'xxx' in '.../node_modules/@dcloudio/uni-ui/lib/xxx'

解决方法: 检查 package.json 文件中的依赖版本,确保所有依赖版本兼容。可以使用 npm installyarn install 重新安装依赖。若涉及第三方库,需确认是否兼容当前 UniApp 版本。

2. 语法错误

错误日志:

javascript 复制代码
ERROR in ./src/pages/index/index.vue
SyntaxError: Unexpected token ';' in JSON at position 100

解决方法: 检查代码中是否有拼写错误、缺少括号或分号,使用 ESLint 或代码编辑器检查语法,确保 JSON 文件无逗号结尾、JS 代码符合 ES 规范,CSS 选择器书写正确。

3. 路径引用错误

错误日志:

javascript 复制代码
Error: ENOENT: no such file or directory, open '.../static/xxx.png'

解决方法:检查文件路径是否正确,检查静态资源路径是否以 /static/ 开头,或使用 @/static/ 绝对路径。使用相对路径或绝对路径时需确保路径有效

4. 平台特有代码未适配

错误日志:

javascript 复制代码
TypeError: uni.requireNativePlugin is not a function (H5环境)

解决方法: 使用条件编译区分平台:

javascript 复制代码
// #ifdef APP-PLUS
const plugin = uni.requireNativePlugin('xxx')
// #endif

5. 组件注册失败

错误日志:

javascript 复制代码
Unknown custom element: <uni-badge> - did you register the component correctly?

解决方法: 确认组件已在 pages.json 或全局组件中正确注册。全局组件需在 main.js 注册,检查组件名称拼写是否正确。

javascript 复制代码
import uniBadge from '@dcloudio/uni-ui/lib/uni-badge/uni-badge.vue'
Vue.component('uni-badge', uniBadge)

6. 分包配置错误

错误日志:

javascript 复制代码
Subpackage loading failed: xxx/subpackage is not found

解决方法: 检查 pages.json 分包路径配置:

json 复制代码
{
  "subPackages": [{
    "root": "subpackage",
    "pages": [...]
  }]
}

7. 原生插件集成问题

错误日志:

javascript 复制代码
Failed to execute 'postMessage' on 'WebView'

解决方法: 确认原生插件已按文档正确配置,Android 需检查 AndroidManifest.xml,iOS 需检查 Info.plist

8.manifest.json 格式错误

json 复制代码
// 错误的 manifest.json 配置
{
  "name": "myApp",
  "appid": "12345",
  "description": "示例应用",
  // 缺少闭合括号

错误日志:

plaintext 复制代码
ERROR: Failed to parse manifest.json
Unexpected end of JSON input
at JSON.parse (<anonymous>)

解决方法:检查 JSON 文件格式,确保所有括号、引号闭合,使用 JSON 校验工具(如 JSONLint)验证文件内容。

9. pages.json 路由配置错误

json 复制代码
// 错误的 pages.json 配置
{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页"
      }
    },
    // 缺少 path 字段
    {
      "style": {
        "navigationBarTitleText": "详情页"
      }
    }
  ]
}

错误日志:

plaintext 复制代码
Error: pages.json 配置错误
Page configuration must contain "path" field.

解决方法:确保每个页面配置包含必填字段(如 path),参考官方文档检查配置完整性。

10. 内存不足

错误日志:
pgsql 复制代码
[Error] Exceeded memory limit
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
  at Map.set (<anonymous>)
  at Function.from (native)
  at Object.823 (./pages/index/index.vue:45:15)
  at __webpack_require__ (bootstrap:63:0)
  at Object.670 (./pages/index/index.vue:15:71)
 
常见触发场景
  • 大列表渲染未使用虚拟滚动
vue 复制代码
<!-- 错误示例 -->
<view v-for="item in hugeList" :key="item.id">
  {{ item.content }}
</view>
  • 未及时销毁大型对象
javascript 复制代码
// 错误示例
data() {
  return {
    cachedData: [] // 持续增长未清理
  }
}
排查方法

通过Chrome开发者工具捕获内存快照

  • 打开Performance面板记录内存变化
  • 使用Memory面板拍摄堆快照对比

检查页面生命周期

javascript 复制代码
onUnload() {
  // 手动释放大型变量
  this.hugeData = null
}
解决方案优化
  • 使用虚拟列表组件
vue 复制代码
<uv-virtual-list :list="hugeList" :height="800" :itemSize="100">
  <template v-slot:default="{ item }">
    <view>{{ item.content }}</view>
  </template>
</uv-virtual-list>
  • 分页加载数据
javascript 复制代码
async loadMore() {
  const res = await api.getList({
    page: this.page++,
    size: 20
  })
  this.list = [...this.list, ...res.data]
}
进阶调试技巧

在manifest.json中配置内存警告阈值

json 复制代码
{
  "h5": {
    "performance": {
      "memoryWarningThreshold": 1024
    }
  }
}

使用uni.onMemoryWarning监听

javascript 复制代码
uni.onMemoryWarning(() => {
  console.log('内存警告触发')
  // 执行内存释放操作
})

11.网络请求错误

(1).跨域问题

错误日志可:

javascript 复制代码
Access to XMLHttpRequest at 'http://example.com/api' from origin 'http://localhost:8080' has been blocked by CORS policy

跨域问题通常发生在开发环境下,因为浏览器会阻止不同源的请求。解决方案包括在服务器端配置CORS头部,或使用本地代理服务器绕过跨域限制。

(2).404接口路径错误

错误日志:

javascript 复制代码
GET http://example.com/api 404 (Not Found)

这类错误通常是由于接口路径拼写错误或服务器端未正确配置路由导致。检查接口路径是否正确,确保服务器端已正确部署相关接口。

(3).400参数格式错误

错误日志:

javascript 复制代码
POST http://example.com/api 400 (Bad Request)

400错误通常表示请求参数格式不正确。检查请求头中的Content-Type是否与数据格式匹配,例如application/jsonapplication/x-www-form-urlencoded。确保请求体中的数据格式与服务器端要求一致。

(4).500服务器端错误
javascript 复制代码
GET http://example.com/api 500 (Internal Server Error)

500错误表示服务器端处理请求时发生了内部错误。检查服务器端日志以获取更详细的错误信息,确认服务器端代码是否存在问题。

(6).网络连接问题

错误日志:

javascript 复制代码
Failed to load resource: net::ERR_CONNECTION_REFUSED

这类错误通常表示客户端无法连接到服务器。检查服务器是否正常运行,网络连接是否稳定,以及是否有防火墙或安全组规则阻止了连接。

UniApp中的网络请求示例

以下是一个简单的UniApp网络请求示例,使用uni.request方法:

javascript 复制代码
uni.request({
  url: 'http://example.com/api',
  method: 'GET',
  data: {
    key1: 'value1',
    key2: 'value2'
  },
  header: {
    'Content-Type': 'application/json'
  },
  success: (res) => {
    console.log('请求成功:', res.data);
  },
  fail: (err) => {
    console.error('请求失败:', err);
  }
});
错误处理建议

在UniApp中,建议对所有网络请求进行错误处理,包括超时设置和异常捕获。例如:

javascript 复制代码
uni.request({
  url: 'http://example.com/api',
  method: 'POST',
  timeout: 5000,
  data: {
    key: 'value'
  },
  success: (res) => {
    if (res.statusCode === 200) {
      console.log('请求成功:', res.data);
    } else {
      console.error('服务器返回错误:', res.statusCode);
    }
  },
  fail: (err) => {
    console.error('请求失败:', err);
  }
});

12. TypeScript 类型错误

(1).类型不匹配错误
javascript 复制代码
error TS2322: Type 'string' is not assignable to type 'number'.
let age: number = "25";
  • 原因:变量 age 被声明为 number 类型,但赋值为字符串 "25"
  • 解决方法:确保赋值类型与声明类型一致,例如改为 let age: number = 25;
(2).缺少必要属性
javascript 复制代码
error TS2741: Property 'name' is missing in type '{ age: number }' but required in type 'Person'.
interface Person {
    name: string;
    age: number;
}
const user: Person = { age: 30 };
  • 原因:Person 接口要求 name 属性,但对象 user 未提供。
  • 解决方法:补全必要属性,例如 const user: Person = { name: "Alice", age: 30 };
(3).函数参数类型不匹配
javascript 复制代码
error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
function square(num: number): number {
    return num * num;
}
square("10");
  • 原因:函数 square 需要 number 类型参数,但调用时传入了字符串 "10"
  • 解决方法:传入正确的类型,例如 square(10)
(4).未识别的属性
javascript 复制代码
error TS2322: Type '{ id: number; title: string; published: boolean; }' is not assignable to type 'Book'.
Object literal may only specify known properties, and 'published' does not exist in type 'Book'.
interface Book {
    id: number;
    title: string;
}
const book: Book = { id: 1, title: "TS Guide", published: true };
  • 原因:Book 接口未定义 published 属性,但对象字面量中包含了该属性。
  • 解决方法:移除多余属性或扩展接口定义。

错误排查通用步骤

  • 查看完整错误日志,定位具体文件和行号
  • 清理项目后重新编译(删除 unpackagenode_modules
  • 对比官方模板检查基础配置
  • 分平台编译缩小问题范围(如仅 H5 或仅 App)

二、处理跨域问题的方法?

1.配置本地开发服务器代理

在项目的 manifest.json 文件中配置 h5devServer 选项,通过代理解决跨域问题

json 复制代码
"h5": {
  "devServer": {
    "proxy": {
      "/api": {
        "target": "http://your-api-domain.com",
        "changeOrigin": true,
        "pathRewrite": {
          "^/api": ""
        }
      }
    }
  }
}

2.使用后端设置 CORS 头

在后端服务中设置允许跨域的响应头,确保前端可以正常访问。常见的 CORS 头设置如下:

plaintext 复制代码
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

3.使用 JSONP 请求

对于仅支持 GET 请求的接口,可以使用 JSONP 方式绕过跨域限制。uniapp 中可以通过 uni.requestdataType 设置为 jsonp 实现:

javascript 复制代码
uni.request({
  url: 'http://your-api-domain.com/api/data',
  dataType: 'jsonp',
  success: (res) => {
    console.log(res.data);
  }
});

4.使用云函数中转请求

通过 uniapp 的云开发功能,将请求发送到云函数,再由云函数转发到目标接口。这种方式可以避免前端直接跨域请求。

javascript 复制代码
// 云函数代码(如腾讯云)
const cloud = require('wx-server-sdk');
cloud.init();
const axios = require('axios');

exports.main = async (event, context) => {
  const res = await axios.get('http://your-api-domain.com/api/data');
  return res.data;
};

5.生产环境使用 Nginx 反向代理

在生产环境中,可以通过 Nginx 配置反向代理解决跨域问题。

nginx 复制代码
location /api {
  proxy_pass http://your-api-domain.com;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
}

注意事项

  • 本地开发时优先使用代理方案,避免修改后端代码。
  • 生产环境确保后端配置了合适的 CORS 头或使用反向代理。
  • JSONP 仅适用于 GET 请求,且需要后端支持。

三、如何捕获并处理全局错误?

1.使用 onError 生命周期钩子

App.vueonLaunch 中,通过 uni.onError 监听全局 JavaScript 错误。适合捕获未被 try-catch 处理的异常:

javascript 复制代码
export default {
  onLaunch() {
    uni.onError((error) => {
      console.error('全局错误:', error);
      // 上报错误到服务器
      uni.request({
        url: 'https://api.example.com/log',
        method: 'POST',
        data: { error: error.stack }
      });
    });
  }
}

2.监听 UnhandledRejection(Promise 错误)

通过 window.addEventListener 捕获未处理的 Promise 异常:

javascript 复制代码
window.addEventListener('unhandledrejection', (event) => {
  console.error('未处理的Promise错误:', event.reason);
  event.preventDefault(); // 阻止默认控制台报错
});

3.封装请求拦截器

在公共请求库中统一处理接口错误

javascript 复制代码
function request(options) {
  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      success: (res) => {
        if (res.statusCode !== 200) {
          reject(new Error(`请求失败: ${res.statusCode}`));
        } else {
          resolve(res.data);
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
  }).catch(err => {
    console.error('请求异常:', err);
    throw err; // 继续抛出以供业务层处理
  });
}

错误处理的最佳实践

分类处理错误

  • 客户端错误:如网络请求失败,提示用户重试。
  • 服务端错误:如 500 状态码,记录日志并反馈给运维。
  • 代码逻辑错误:如 undefined 变量,开发阶段应通过 ESLint 提前拦截。

错误上报机制

集成 Sentry 或自建日志服务,关键代码示例:

javascript 复制代码
uni.onError((err) => {
  sentry.captureException(err); // Sentry上报
});

用户友好提示

在捕获错误后,使用 uni.showToast 避免直接暴露原始错误信息:

javascript 复制代码
uni.showToast({
  title: '操作失败,请稍后重试',
  icon: 'none'
});

注意事项

  • 小程序限制:部分平台(如微信小程序)无法捕获全部全局错误,需结合平台 API 补充。
  • 异步错误setTimeoutPromise 中的错误需单独处理,无法被 onError 捕获。
  • 生产环境调试:建议关闭详细错误提示,仅保留必要日志。

四、小程序白屏

检查网络连接

确保用户的网络连接稳定,弱网或断网可能导致资源加载失败。可以通过监听网络状态变化,提示用户检查网络。

javascript 复制代码
wx.onNetworkStatusChange(function(res) {
  if (!res.isConnected) {
    wx.showToast({ title: '网络不可用', icon: 'none' });
  }
});

优化代码包体积

代码包体积过大会导致加载时间过长甚至白屏。通过分包加载、移除未使用的代码或资源来减小体积。在app.json中配置分包:

json 复制代码
{
  "subPackages": [
    {
      "root": "packageA",
      "pages": ["pages/cat", "pages/dog"]
    }
  ]
}

预加载关键资源

onLoad生命周期中提前请求关键数据,避免渲染阻塞。使用wx.request预加载数据:

javascript 复制代码
Page({
  onLoad() {
    wx.request({
      url: 'https://api.example.com/data',
      success: (res) => { this.setData({ keyData: res.data }); }
    });
  }
});

启用骨架屏

在数据加载完成前展示骨架屏,提升用户体验。通过wx:if控制骨架屏与内容的切换:

html 复制代码
<view wx:if="{{isLoading}}">
  <!-- 骨架屏结构 -->
</view>
<view wx:else>
  <!-- 实际内容 -->
</view>

检查页面路由堆栈

页面路由层级过深可能导致内存不足。避免不必要的navigateTo,使用redirectTo替换不需要返回的页面:

javascript 复制代码
wx.redirectTo({ url: '/pages/home/index' });

监控异常并上报

通过onError捕获全局错误,结合wx.reportMonitor上报白屏相关信息:

javascript 复制代码
App({
  onError(err) {
    wx.reportMonitor('white_screen', 1);
    console.error('全局错误:', err);
  }
});

兼容性处理

检查基础库版本,过低版本可能导致渲染异常。在app.json中设置最低支持版本:

json 复制代码
{
  "envVersion": "develop",
  "libVersion": "2.15.0"
}

内存管理优化

避免在data中存储过大对象,及时清理定时器和事件监听。在onUnload中释放资源:

javascript 复制代码
Page({
  onUnload() {
    clearInterval(this.timer);
    this.eventEmitter.off();
  }
});
相关推荐
2501_915921434 分钟前
Windows 如何上架 iOS 应用?签名上传全流程 + 工具推荐
android·ios·小程序·https·uni-app·iphone·webview
天天扭码8 分钟前
很全面的前端面试题——计算机网络篇(上)
前端·网络协议·面试
JSON_L10 分钟前
Vue 详情模块 3
前端·javascript·vue.js
哀木21 分钟前
关于 one drive 上传功能的前端接入(未完成)
前端
大熊学员1 小时前
HTML与JavaScript的羁绊
前端·css·html
Mike_Wuzy1 小时前
【前端】CSS基础知识及基本应用
前端·css
啃火龙果的兔子1 小时前
WebView 中控制光标
前端
流星先生!1 小时前
前端小数点处理
开发语言·前端·javascript
不是二师兄的八戒2 小时前
PDF转图片工具技术文档(命令行版本)
前端·python·pdf
拾光拾趣录2 小时前
🔥9道题穿透JS底层:堆栈/异步/执行栈连环问,第5题99%人翻车?📉
前端·面试