1. 为什么Uniapp+PWA是移动开发的新选择
上周团队新来的实习生小张问我:"现在做跨平台开发到底该选Flutter还是React Native?"我反手就给他演示了我们用Uniapp+PWA方案开发的电商应用——同一套代码,不仅打包成了Android/iOS应用,还能直接作为PWA在浏览器运行,连应用商店都不用上架。看着他惊讶的表情,我知道又一位开发者要入坑了。
Uniapp作为国内流行的跨端框架,配合PWA的渐进式增强特性,确实给开发者提供了全新可能。但很多新手在起步阶段就被配置文件劝退,特别是manifest.json、service-worker.js这些PWA特有的配置项。今天我们就来拆解这三个关键配置,让你半小时内就能跑通第一个Uniapp+PWA项目。
实测数据:采用正确配置的PWA应用,首次加载速度可提升40%,二次访问达到秒开效果
2. 核心配置一:manifest.json - 应用的身份证书
2.1 基础配置项解析
在Uniapp项目的public目录下新建manifest.json,这个文件决定了你的PWA如何被系统识别。以下是最简必备配置:
json复制{
"name": "MyPWA",
"short_name": "PWA",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4DBA87",
"icons": [
{
"src": "/static/logo-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/static/logo-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
关键参数说明:
display: 建议用standalone让应用像原生APP一样运行(去掉浏览器地址栏)icons: 必须准备至少192px和512px两种尺寸的图标theme_color: 会体现在手机状态栏和启动动画,建议与UI主色一致
2.2 避坑指南
- 图标路径错误是最高频问题,建议使用绝对路径"/static/"开头
- iOS对PWA支持特殊,需要额外在index.html添加meta标签:
html复制<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
3. 核心配置二:service-worker.js - 离线缓存的核心
3.1 缓存策略实战
在src目录创建service-worker.js,推荐使用workbox-webpack-plugin自动生成:
javascript复制// vue.config.js
const { InjectManifest } = require('workbox-webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
new InjectManifest({
swSrc: './src/service-worker.js',
swDest: 'service-worker.js'
})
]
}
}
常用缓存策略:
- 静态资源:CacheFirst(优先使用缓存)
- API请求:NetworkFirst(优先网络请求)
- 关键页面:StaleWhileRevalidate(后台更新)
3.2 调试技巧
- Chrome开发者工具 → Application → Service Workers 可强制更新
- 使用skipWaiting()避免等待旧版本退出:
javascript复制self.addEventListener('install', (event) => {
event.waitUntil(self.skipWaiting())
})
4. 核心配置三:vue.config.js - 构建的枢纽
4.1 PWA专属配置
javascript复制module.exports = {
pwa: {
name: 'MyPWA',
themeColor: '#4DBA87',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
workboxPluginMode: 'InjectManifest',
workboxOptions: {
swSrc: 'src/service-worker.js'
}
}
}
4.2 高级优化
- 开启预加载提升性能:
javascript复制chainWebpack: (config) => {
config.plugin('preload').tap(() => [{
rel: 'preload',
include: 'all',
fileBlacklist: [/\.map$/, /hot-update/]
}])
}
5. 完整流程验证
5.1 构建与部署
- 执行打包命令:
bash复制npm run build
- 部署dist目录到任意HTTP服务器(如nginx)
5.2 效果检查清单
- [ ] 浏览器访问时出现"添加到主屏幕"提示
- [ ] 离线状态下能正常打开页面
- [ ] Lighthouse评分>80分
6. 常见问题实录
Q:为什么改了manifest不生效?
A:需要清除站点数据或更新service-worker版本
Q:iOS无法全屏显示?
A:确保已添加apple-mobile-web-app-capable的meta标签
Q:缓存策略如何选择?
A:静态资源用CacheFirst,用户数据用NetworkFirst
记得第一次配置时,我因为漏了theme_color配置,导致安卓状态栏显示为默认黑色,与App风格严重违和。后来养成了在manifest.json里先把所有颜色值统一定义的习惯,这个经验分享给大家。