ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

VUX 项目实践:Vue 组件异步加载与 Webpack Code Splitting 完整指南

VUX 项目实践:Vue 组件异步加载与 Webpack Code Splitting 完整指南 UI组件前端【免费下载链接】vuxMobile UI Components based on Vue WeUI项目地址https://gitcode.com/gh_mirrors/vu/vux点击查看免费下载本指南围绕 VUX基于 Vue 与 WeUI 的移动端 UI 组件库官方开发文档中的「异步加载组件」章节展开讲解如何在移动端 Vue 应用中利用 Webpack 的 code splitting 机制按路由懒加载组件覆盖() import()的语法演进、vue-loader 版本差异以及组件重复打包的优化方案并结合本仓库的构建配置与源码给出可直接落地的实践依据。读完本文你将掌握在 VUX 项目中配置异步路由组件、规避重复打包、缩小首屏 chunk 体积的完整套路。为什么移动端需要异步加载组件将所有页面组件一次性打包进一个 bundle 是一种很浪费资源和考验用户耐心的做法尤其在移动端移动端网络环境不稳定、带宽有限一次性下载全部代码会显著拉长首屏等待时间用户可能只访问其中一两个页面却要为整个应用的全部代码买单大型应用路由数量动辄几十上百单文件 bundle 的体积会迅速膨胀。解决思路是代码分割Code Splitting把应用代码拆分成多个 chunk仅在切换到特定路由时才加载对应的代码块。Webpack 原生提供了这套机制Vue Router 的异步组件语法与它天然配合可以实现按路由加载的按需体验。VUX 官方文档在 docs/zh-CN/development/vue-webpack-code-splitting-async.md 中专门讲解了这一实践这也是官方推荐 VUX 项目配合vux2模板与 vue-router采用的页面加载策略。使用方法用() import()实现按路由加载基础写法webpack提供了 code splitting 能力你可以按照下面的写法实现当切换到特定路由时才加载代码// 路由配置文件中 const Foo () import(./Foo.vue)将其放入 vue-router 的路由配置后Foo.vue及其依赖会被编译成独立的 chunk只有当用户导航到对应路由时该 chunk 才被动态加载。仓库中的真实示例位于 packages/vue-cli-3-example/src/router.js其中首页Home采用静态导入About页面则使用路由级代码分割import Vue from vue import Router from vue-router import Home from ./views/Home.vue Vue.use(Router) export default new Router({ routes: [ { path: /, name: home, component: Home }, { path: /about, name: about, // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () import(/* webpackChunkName: about */ ./views/About.vue) } ] })注意这里的魔法注释/* webpackChunkName: about */它用于给生成的 chunk 命名让产物输出为可读的about.[hash].js而不是数字编号便于在浏览器 Network 面板中定位与排查问题。这个示例项目还配套提供了 packages/vue-cli-3-example/vue.config.js 与 packages/vue-cli-3-example/package.json可作为 Vue CLI 3 环境下异步组件的完整参考工程。vue-loader13.0.0 前后的语法差异异步组件写法有一个重要的版本分水岭vue-loader13.0.0语法有所变更详见 vue-loader v13.0.0 的发布说明具体表现为// vue-loader13.0.0 之前 const Foo () import(./Foo.vue) // 在 Vue 2.4 vue-router 2.7 版本下可以正确运行 // vue-loader13.0.0 const Foo () import(./Foo.vue).then(m m.default)两种写法差异的根源在于 ES Module 互操作interop行为的变化vue-loader 13 之前loader 产出的模块对象本身就是组件对象即module.exports Fooimport()返回的 Promise 直接 resolve 出组件本身因此() import(./Foo.vue)即可直接使用vue-loader 13 及以后输出遵循标准 ES Module 语义import()返回的模块命名空间对象带有一个default属性指向真正的组件因此需要.then(m m.default)取出默认导出。如果你正在使用较新的 vue-loader / Vue CLI 3 环境请始终采用带.then(m m.default)的写法。仓库源码中的实际用法本仓库的文档站构建配置 build/vux-config.js 中js-parser插件在构建时动态生成全部 demo 路由其生成的路由组件正是异步写法str.push({ path: ${path}, component: () import(./demos/${filename}.vue).then(m m.default) }) // 404 页面同样异步加载 str.push({ path: *, component: () import(./demos/NotFoundComponent.vue).then(m m.default) })而文档站的入口 src/main.js 中只有一行占位声明// The following line will be replaced with by vux-loader with routes in ./demo_list.json const routes []随后由build/vux-config.js通过source.replace(const routes [], const routes str)注入异步路由定义。这印证了两点在 VUX 的实际工程中.vue页面组件通过异步导入 .then(m m.default)的方式被注册为路由组件每个 demo 页面都被拆分为独立 chunk仅在访问对应路由时才被加载——这正是官方文档按路由加载策略在仓库内的真实落地。组件打包问题重复打包与全局注册问题现象如果你在不同的、进行了代码分割的.vue文件里引入了相同的组件打包时两个路由的代码都会重复打包该组件。举个具体场景PageA.vue和PageB.vue都import Xxx from xxx而它们属于两个不同的异步 chunk。Webpack 在默认配置下会把这个公共依赖分别打入两个 chunk导致产物总字节数膨胀用户下载了双份相同的代码命中浏览器缓存的效果变差首屏需要加载的 chunk 里混入了本可共享的公共代码。解决方案在 main.js 全局注册你可以对重复使用的组件在main.js中进行全局注册以减少相应 chunk file 的大小并提高下载速度// src/main.js import Vue from vue import { Group, Cell } from vux Vue.component(group, Group) Vue.component(cell, Cell)全局注册后group、cell等标签在任何页面中直接可用各异步路由的 chunk 中不再需要重复携带这些组件的实现代码从而显著瘦身。这一做法正是仓库自身的实践在 src/main.js 中文档站从vux一次性引入Group、Cell两个组件并进行全局注册随后所有 demo 页面直接使用group/cell标签无需在各自的路由 chunk 中重复打包import { Group, Cell, DatetimePlugin, CloseDialogsPlugin, ConfigPlugin, BusPlugin, LocalePlugin, DevicePlugin, ToastPlugin, AlertPlugin, ConfirmPlugin, LoadingPlugin, WechatPlugin, AjaxPlugin, AppPlugin } from vux Vue.component(group, Group) Vue.component(cell, Cell)同理常用插件ToastPlugin、AlertPlugin、ConfirmPlugin、LoadingPlugin、DevicePlugin、AjaxPlugin等也在 src/main.js 中通过Vue.use(...)一次性安装页面 chunk 无需重复引入。进阶利用 Webpack 公共代码抽取除了全局注册Webpack 层面还有一类互补手段——抽取公共 chunk。仓库生产构建配置 build/webpack.prod.conf.js 使用CommonsChunkPlugin将 vendor 依赖与公共模块单独拆出new webpack.optimize.CommonsChunkPlugin({ // ... }), new webpack.optimize.CommonsChunkPlugin({ name: vendor, // 抽取第三方公共依赖 chunks: [vendor] })在 Webpack 4如 packages/vue-cli-3-example 使用的 Vue CLI 3 环境中这一职责由内置的splitChunks与runtimeChunk配置接管配合optimization.splitChunks.chunks: all即可自动完成公共模块的智能抽取与全局注册方案相辅相成。小结与排查建议在 VUX或任何 Vue 2 vue-router 2.7 webpack项目中落地异步加载请记住以下要点关注点建议路由组件使用() import(./Xxx.vue).then(m m.default)vue-loader 13 环境chunk 命名使用/* webpackChunkName: xxx */魔法注释便于调试高频复用组件在 main.js 中Vue.component()全局注册公共依赖借助CommonsChunkPluginwebpack 3或splitChunkswebpack 4抽取 vendor版本兼容确认vue-loader主版本后再决定是否保留.then(m m.default)若发现某个异步路由首次跳转时白屏或报default is not a function之类的错误优先检查是否因 vue-loader 版本升级导致异步组件写法未同步更新若发现产物体积异常偏大则优先排查是否存在跨 chunk 的重复组件导入并考虑移入全局注册。如需了解 VUX 与 vue-router 的配合细节如组件link属性直接支持路由参数、内置 vue-router 的vux2模板等可进一步阅读 docs/zh-CN/development/router.md。赞分享UI组件前端【免费下载链接】vuxMobile UI Components based on Vue WeUI项目地址https://gitcode.com/gh_mirrors/vu/vux点击查看免费下载相关推荐OBS Studio日志系统终极指南快速诊断流媒体录制问题的完整教程OBS Studio日志系统终极指南快速诊断流媒体录制问题的完整教程 OBS Studio作为业界领先的开源流媒体录制软件其强大的日志系统是开发者和系统管理音视频直播屏幕录制桌面应用视频Gatsby 组件级 Code Splitting 与 SSR 实践loadable-components 完整指南Gatsby 组件级 Code Splitting 与 SSR 实践loadable components 完整指南 本文是一份基于 Gatsby 官方仓库中前端静态站点Web框架webpack 按需加载入门用 require.ensure 实现 Code Splitting 的完整示例剖析webpack 按需加载入门用 require.ensure 实现 Code Splitting 的完整示例剖析 本指南围绕 webpack 官方示例中的最小前端构建开发工具上一篇ReaxFF力场在JAX-MD中的应用从参数文件到化学反应模拟下一篇Kubernetes安全最佳实践使用kOps构建安全集群创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表