尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

@vue/cli-plugin-pwa 插件完全指南:Workbox 配置、Manifest 注入与 Service Worker 实战

@vue/cli-plugin-pwa 插件完全指南:Workbox 配置、Manifest 注入与 Service Worker 实战 vue/cli-plugin-pwa 插件完全指南Workbox 配置、Manifest 注入与 Service Worker 实战【免费下载链接】vue-cli️ webpack-based tooling for Vue.js Development项目地址: https://gitcode.com/gh_mirrors/vu/vue-cli导读vue/cli-plugin-pwa是 Vue CLI 官方提供的 PWAProgressive Web App插件它基于 Workbox 在构建阶段自动生成 Service Worker、注入 Web App Manifest 与各类移动端元标签让 Vue 项目开箱即用地获得离线缓存、添加到主屏幕等能力。本文以 Vue CLI 仓库中 pwa 官方文档含俄语版 docs/ru/core-plugins/pwa.md为核心骨架结合插件源码逐项讲解全部配置项、开发/生产环境的 Service Worker 行为差异、本地测试方法以及底层实现原理读完即可在自己的 Vue 项目中独立配置、调试与验证 PWA 能力。插件工作方式开发与生产环境的行为差异该插件添加的 Service Worker只在生产环境生效——即只有执行npm run build或yarn build构建时才启用。官方明确不推荐在开发模式下启用 Service Worker因为这会带来使用了先前缓存的旧资源、却未包含最新的本地改动的风险。开发模式下插件改为提供noopServiceWorker.js文件。这个 Service Worker 文件是有效的空操作no-op它会重置此前在同一host:port组合上注册过的任何其他 Service Worker从而避免生产版 Service Worker 劫持开发环境页面的问题。如果需要本地测试 Service Worker正确做法是先构建应用再从构建输出目录dist启动一个简单的 HTTP 服务器并建议使用浏览器的无痕隐身窗口以避免浏览器自身缓存带来的干扰。源码层面的佐证在 index.js 中只有process.env.NODE_ENV production时才通过 webpack-chain 注册workbox插件来生成/service-worker.js非生产环境则完全不注册 Workbox。开发模式下index.js 通过api.configureDevServer挂载 noopServiceWorkerMiddleware.js该中间件拦截req.url /service-worker.js的请求返回 noopServiceWorker.js 的文本内容。该 noop 脚本在activate事件中遍历所有window类型的客户端并强制navigate刷新让开发页面立即脱离旧 Service Worker 的控制。需要留意 noopServiceWorkerMiddleware.js 源码中的提示如果生产服务器对/service-worker.js设置了很长的缓存头noop 方案可能无法立即生效此时需要手动在 Chrome DevTools → Application → Service Workers 中注销该 Service Worker。安装与项目接入在已有项目中安装vue add pwa该命令执行的 generator/index.js 会完成三件事向package.json的dependencies添加register-service-worker当前版本约束为^1.7.2在入口文件如src/main.js注入import ./registerServiceWorker渲染模板文件包括public/img/icons/下的全套图标android-chrome、apple-touch-icon、favicon、msapplication-icon、safari-pinned-tab 等、public/robots.txt以及 src/registerServiceWorker.js。生成的 registerServiceWorker.js 模板仅在process.env.NODE_ENV production时调用register(${process.env.BASE_URL}service-worker.js, {...})注册 Service Worker并暴露了ready、registered、cached、updatefound、updated、offline、error七种回调用于打印内容已缓存可离线使用新内容可用请刷新等状态日志。注意模板的public/目录中并不存在manifest.json——它是由插件在构建期根据配置自动生成的详见下文manifestOptions与manifestPath小节。配置入口PWA 配置通过vue.config.js文件中的pwa属性或package.json中的vue字段完成module.exports { pwa: { // 全部配置项见下文 } }核心配置项逐项详解pwa.workboxPluginMode在底层 workbox-webpack-plugin 支持的两种模式中二选一GenerateSW默认值每次重新构建应用时生成一个新的 Service Worker 文件适合大多数开箱即用场景InjectManifest从一个已有的 Service Worker 文件出发生成该文件的副本并把 precache manifest预缓存清单注入其中适合需要对 Service Worker 逻辑做精细自定义的场景。Workbox 官方提供了该用哪个插件指南帮助选择。源码佐证在 index.js 中workboxPluginMode默认取GenerateSW并且会校验该值是否为workbox-webpack-plugin模块的合法导出键否则抛出错误并列出所有合法模式const workboxPluginMode userOptions.workboxPluginMode || GenerateSW const workboxWebpackModule require(workbox-webpack-plugin) if (!(workboxPluginMode in workboxWebpackModule)) { throw new Error( ${workboxPluginMode} is not a supported Workbox webpack plugin mode. Valid modes are: ${Object.keys(workboxWebpackModule).join(, )} ) }pwa.workboxOptions透传给底层workbox-webpack-plugin的配置对象。采用 App Shell 模板并处于GenerateSW模式时可通过配置navigateFallback让所有页面在离线时都能加载navigateFallback: index.html更多受支持的值请参阅GenerateSW或InjectManifest的完整配置指南。源码佐证插件会先合并一层默认值再传入 Workboxindex.jsconst defaultOptions { exclude: [ /\.map$/, /img\/icons\//, /favicon\.ico$/, /^manifest.*\.js?$/ ] } const defaultGenerateSWOptions workboxPluginMode GenerateSW ? { cacheId: name } : {} const workBoxConfig Object.assign(defaultOptions, defaultGenerateSWOptions, userOptions.workboxOptions)即默认排除 sourcemap、img/icons/下的图标、favicon.ico和 manifest 相关脚本不参与预缓存GenerateSW模式下还会用package.json中的name作为cacheId。你传入的workboxOptions会覆盖这些默认值。pwa.name默认值package.json中的name字段用作生成 HTML 中apple-mobile-web-app-title元标签的值。注意如果需要与之一致还需要同步修改public/manifest.json中的name。源码佐证HtmlPwaPlugin.js 中把name写入meta nameapple-mobile-web-app-title content...同时 index.js 把api.service.pkg.name作为 name 传入插件。pwa.themeColor默认值#4DBA87Vue 品牌绿用于生成 HTML 中的meta nametheme-color content...影响移动端浏览器地址栏颜色同时作为默认的 manifesttheme_color与mask-icon的color值。pwa.msTileColor默认值#000000用于生成 Windows 磁贴相关元标签meta namemsapplication-TileColor content...。pwa.appleMobileWebAppCapable默认值no用于生成meta nameapple-mobile-web-app-capable content...。默认取no是因为 iOS 11.3 之前没有对 PWA 的完善支持详情可参考 这篇文章。pwa.appleMobileWebAppStatusBarStyle默认值default用于生成meta nameapple-mobile-web-app-status-bar-style content...控制 iOS 全屏状态下状态栏样式可选值通常为default、black、black-translucent。pwa.assetsVersion默认值当需要给图标和 manifest 追加版本号以绕开浏览器缓存时使用。设置后会为图标和 manifest 的 URL 追加?vpwa.assetsVersion查询参数。源码佐证HtmlPwaPlugin.js 中const assetsVersionStr assetsVersion ? \?v${assetsVersion} : 随后该字符串被拼接到 favicon、manifest、apple-touch-icon、mask-icon 等所有标签的href 上。pwa.manifestPath默认值manifest.json应用 manifest 的路径。如果该值是一个完整的 URL插件在构建时就不会在 dist 目录中生成manifest.json而是直接引用该外部地址。源码佐证HtmlPwaPlugin.js 中通过isHrefAbsoluteUrl匹配http(s)://判断只有当 manifestPath 不是绝对 URL 时才会在compilation.hooks.processAssets的PROCESS_ASSETS_STAGE_ADDITIONS阶段向构建产物写入manifest.json资源。pwa.manifestOptions默认值{}用于生成manifest.json的对象。若对象中未定义以下属性则回退使用pwa顶层选项或插件内置默认值属性默认来源namepwa.nameshort_namepwa.namestart_url.displaystandalonetheme_colorpwa.themeColoricons内置的四枚图标见下方默认数组内置的默认icons数组见 HtmlPwaPlugin.js[ { src: ./img/icons/android-chrome-192x192.png, sizes: 192x192, type: image/png }, { src: ./img/icons/android-chrome-512x512.png, sizes: 512x512, type: image/png }, { src: ./img/icons/android-chrome-maskable-192x192.png, sizes: 192x192, type: image/png, purpose: maskable }, { src: ./img/icons/android-chrome-maskable-512x512.png, sizes: 512x512, type: image/png, purpose: maskable } ]源码佐证除了上述icons、start_url、display默认值外HtmlPwaPlugin.js 中还内置了background_color: #000000作为默认最终生成的 manifest 由Object.assign(publicOptions, defaultManifest, manifestOptions)计算得出——publicOptions提供name/short_name/theme_colordefaultManifest提供图标与start_url/display/background_color用户传入的manifestOptions拥有最高优先级。另外在 index.js 中如果项目里存在public/manifest.json且用户未配置manifestOptions插件会直接读取该文件作为 manifest 内容来源若两者同时存在插件会发出警告——public/manifest.json将被忽略以pwa.manifestOptions为准。pwa.manifestCrossorigin默认值undefined设置生成 HTML 中 manifestlink标签的crossorigin属性值。当 PWA 位于需要认证的代理之后时可能需要设置它。合法的 cross-origin 取值anonymous、use-credentials等可参考 MDN 文档。源码佐证HtmlPwaPlugin.js 中只有当manifestCrossorigin为真值时才在 manifest link 上追加crossorigin属性ui.js 的图形化配置则提供nullnone、anonymous、use-credentials三个选项。pwa.iconPaths默认值{ faviconSVG: img/icons/favicon.svg, favicon32: img/icons/favicon-32x32.png, favicon16: img/icons/favicon-16x16.png, appleTouchIcon: img/icons/apple-touch-icon-152x152.png, maskIcon: img/icons/safari-pinned-tab.svg, msTileImage: img/icons/msapplication-icon-144x144.png }以上默认值与 HtmlPwaPlugin.js 源码中的defaultIconPaths一致俄语版文档中的默认值示例未列出faviconSVG完整定义以源码为准。按需修改这些值以使用不同的图标路径。自 v4.3.0 起可将某个值设为null以不包含该图标——源码中正是通过if (iconPaths.faviconSVG ! null)这类判空来实现见 HtmlPwaPlugin.js。重要提示iconPaths中的图标仅用于在 HTML 的head中生成元标签favicon、apple-touch-icon、mask-icon、msapplication-TileImage 等。若要修改 manifest 中的图标路径请使用pwa.manifestOptions.icons。完整配置示例// 文件 vue.config.js module.exports { // ...其他 vue-cli 插件选项... pwa: { name: My App, themeColor: #4DBA87, msTileColor: #000000, appleMobileWebAppCapable: yes, appleMobileWebAppStatusBarStyle: black, // manifest 设置 manifestOptions: { display: landscape, background_color: #42B883 // ...其他 manifest 设置... }, // workbox 插件设置 workboxPluginMode: InjectManifest, workboxOptions: { // InjectManifest 模式下必须指定 swSrc swSrc: dev/sw.js, // ...其他 Workbox 设置... } } }底层实现HtmlPwaPlugin 注入了什么插件通过 HtmlPwaPlugin.js 挂在html-webpack-plugin的钩子上源码中以vue-cli:pwa-html-plugin标识在alterAssetTagGroups阶段向 HTML 的head注入以下标签faviconSVG/32x32/16x16支持?v版本参数且beforeEmit阶段会用!--[if IE]...![endif]--条件注释包裹基础模板中的 faviconlink relmanifest href...可选crossorigin属性meta nametheme-coloriOS Safari 三件套apple-mobile-web-app-capable、apple-mobile-web-app-status-bar-style、apple-mobile-web-app-titlelink relapple-touch-icon、link relmask-icon colorthemeColorWindows 磁贴msapplication-TileImage与msapplication-TileColor。所有相对路径的标签 href 都会拼接 webpack 的output.publicPath见getTagHref绝对 URL 则原样保留。注入的 webpack-chain 规则插件通过api.chainWebpack注册以下两条规则见 index.jsconfig.plugin(pwa)使用HtmlPwaPlugin并置于html插件之后.after(html)负责注入 PWA 相关标签与生成 manifestconfig.plugin(workbox)仅在NODE_ENV production且构建目标为app时注册使用workbox-webpack-plugin的GenerateSW或InjectManifest负责生成/service-worker.js。若process.env.VUE_CLI_BUILD_TARGET存在且不等于app例如构建库或 Web Components插件会直接跳过不注入任何内容。图形化配置Vue CLI UI插件还提供了 ui.js 集成到 Vue CLI UIorg.vue.pwa配置面板支持通过界面编辑vue.config.js中的pwa配置与public/manifest.json包括workboxPluginModeGenerateSW/InjectManifest 下拉选择、name、themeColor、msTileColor、appleMobileWebAppStatusBarStyle、manifestCrossorigin等字段并在项目配置视图打开时提供打开 vue.config.js / manifest.json的操作建议。注意background_color仅在不存在public/manifest.json时才写入pwa.manifestOptions.background_color否则直接写入 manifest 文件。如何验证 PWA 是否生效仓库中的集成测试tests/pwaPlugin.spec.js 给出了完整验证思路可作为实践清单构建后应生成dist/manifest.json与dist/img/icons/android-chrome-512x512.png等 PWA 专属产物dist/index.html中应包含link relmanifest href/manifest.json、!--[if IE]link relicon href/favicon.ico![endif]--以及meta nameapple-mobile-web-app-capable contentno等注入标签src/main.js中应存在import ./registerServiceWorker从dist目录启动 HTTP 服务器并用无头浏览器访问后控制台应出现 Workbox 的日志Content has been cached for offline use与App is being served from cache by a service worker。相关文档与源码入口官方文档英文docs/core-plugins/pwa.md俄语版见 docs/ru/core-plugins/pwa.md插件主入口packages/vue/cli-plugin-pwa/index.js标签注入与 manifest 生成packages/vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js开发环境 noop Service Workerpackages/vue/cli-plugin-pwa/lib/noopServiceWorker.js 与其中间件 noopServiceWorkerMiddleware.js项目接入生成器packages/vue/cli-plugin-pwa/generator/index.js 与注册模板 registerServiceWorker.js集成测试packages/vue/cli-plugin-pwa/tests/pwaPlugin.spec.jsUI 配置面板packages/vue/cli-plugin-pwa/ui.js【免费下载链接】vue-cli️ webpack-based tooling for Vue.js Development项目地址: https://gitcode.com/gh_mirrors/vu/vue-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表