Vue3项目框架搭建封装,一次学习,终身受益【万字长文,满满干货】(一)

简介: Vue3项目框架搭建封装,一次学习,终身受益【万字长文,满满干货】

1686891111992.jpg

前言

入职新公司后,发现代码仓库里,项目搭建的比较乱,每个项目使用的都不太一样,不利于统一规范化管理,我结合已有的业务积累和优秀的实践经验,搭建了一套移动端模板项目,在这里和大家做一个分享。

一般来说,大部分前端去公司都是干活,拧螺丝钉的,项目的框架都是架构师或者小组负责人搭建封装好的,我们经过简单学习,直接开发就好,没有自己去搭建封装的机会,没有做过,总是会下意识觉得很简单,其实让自己去做还是有很多困难的。

如果想做到前端负责人,项目搭建封装是必须掌握的,看了我这篇文章

如果能有所收获,或者帮助到大家,那真是太好了!

没有人甘于平庸,我想你也是!

源码地址:github.com/Yinzhuo1997…文档地址:yinzhuo19970516.github.io/

功能点

本项目是基于vue-cli4.x,webpack5,对vue-cli提供的框架做的二次封装,主要封装的功能点主要有以下

  • -   多入口打包
  • -   自动化生成项目基本模版
  • -   pinia状态管理库
  • -   持久化存储插件封装
  • -   路由动画的封装
  • -   axios 二次封装
  • -   less sass变量,函数的处理
  • -   viewport 适配方案
  • -   配置多环境变量
  • -   vconsole.js
  • -   链式操作符
  • -   入口加载动画

多入口打包

适用场景

移动端开发,一般情况,我们项目开发只需要一个配置一个入口,一个模版文件。

但是有时候又明显不够用,移动端,同一个业务下,同类型的项目,就很适合放在一个项目下做多入口打包。

比如以下场景:

  • 活动项目,同类型活动多期迭代,不同类型的活动,新增一个活动就重新建立一套项目,维护成本很大,此时就很适合一个大的活动项目里,去新增多个活动页面入口。
  • 当我们去写App的内嵌h5页面时,每个流程其实都是相互独立的,都是在一个app下,也很适合,多入口,维护在一个项目里。

优势

  • 多入口,项目内各个入口独立,低耦合,不会相互影响。
  • 发布成本低,可以维护在一个项目里,不用新建多个项目。
  • 结构清晰,可维护性比较好。

如果我们全部使用单入口,也就是vue官方提供的框架,可以设想一下,如果是活动页面,我们把所有活动的页面都定义在一个入口里,router,store全部在一块,项目耦合会越来越严重,路由名也会重合率越来越高!

项目结构

如下图所示,我们在src目录下面,新增了module目录,用来存放我们的多个项目入口,page1 和page2 就是我用来演示的两个项目文件。

1686891159388.jpg

前置依赖库

node 的 glob库

glob 其实是linux shell默认的通配符,主要是做文件匹配,glob 模式通常用来匹配目录以及文件

这里介绍的是node的一个方法库glob

glob 在一般用于文件系统中定位文件

主要用到了同步搜索文件API

glob.sync(pattern, [options])

  • pattern {String} 待匹配的模式
  • options {Object}
  • return: {Array} 匹配模式的文件名

vue-cli的 pages配置

vue-cli 接收一个参数pages,用来控制输入文件,输出文件

详情可参考文档pages

官方例子如下

比较重要的三个参数就是 entry template filename

page 的入口,模板来源, 在 dist/index.html 的输出

下面这端代码是vue-cli的官方说明

module.exports = {
  pages: {
    index: {
      // page 的入口
      entry: 'src/index/main.js',
      // 模板来源
      template: 'public/index.html',
      // 在 dist/index.html 的输出
      filename: 'index.html',
      // 当使用 title 选项时,
      // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
      title: 'Index Page',
      // 在这个页面中包含的块,默认情况下会包含
      // 提取出来的通用 chunk 和 vendor chunk。
      chunks: ['chunk-vendors', 'chunk-common', 'index']
    },
    // 当使用只有入口的字符串格式时,
    // 模板会被推导为 `public/subpage.html`
    // 并且如果找不到的话,就回退到 `public/index.html`。
    // 输出文件名会被推导为 `subpage.html`。
    subpage: 'src/subpage/main.js'
  }
}

devServer 的setupMiddlewares

提供执行自定义函数和应用自定义中间件的能力。

我们可以在devServer 启动项目之前,做一些自定义的处理

我在启动时渲染了一段 html

 devServer: {
    host: '0.0.0.0',
    setupMiddlewares: (middleware, devServer) => {
      devServer.app.get('', (_, response) => {
        response.write(html)
        response.end()
      })
      return middleware
    },
    proxy: {}
 }

核心代码实现

const entryName = ''
const entry1 = glob.sync('src/main.js') // 单入口
const entry2 = glob.sync('src/module/*/main.js') // 多入口
const entryList = [...entry1, ...entry2]
const pages = {} //pages 参数
let html = '' // 要渲染的html
entryList.forEach(filePath => {
  const name1 = filePath.match(/src/main.js$/) // 单入口
  const name2 = filePath.match(/src/module/(\w+)/main.js$/) // 多入口
  const name = name1 ? name1[1] : name2[1]
  const filename = name1 ? name + '/index' : name
  if (filename === entryName || !entryName) {
    const pagePath = glob.sync(`src/module/${name}/index.html`)[0] 
    // 读文件夹下的index.html文件
    pages[name] = {
      entry: filePath,
      template: pagePath || 'public/index.html',
      // 如果没有自动去取public下的通用index.html
      filename: filename + '/index.html'
    }
    // 构造html 结构
    html += `<a href="${filename}/">${filename}/</a><br>`
  }
})
console.log(pages)

pages 结构

hehehhe 项目的 index.html 文件是取自public,其他的是取自本项目目录下

考虑到部分页面会有在入口文件引用第三方的库的情况,比如swiper,jq。

所以这里设置的比较灵活,可以直接用通用的项目模版,也可以在项目里自定义模版。

{
  hehehe: {
    entry: 'src/module/hehehe/main.js',
    template: 'public/index.html',
    filename: 'hehehe/index.html'
  },
  page1: {
    entry: 'src/module/page1/main.js',
    template: 'src/module/page1/index.html',
    filename: 'page1/index.html'
  },
  page2: {
    entry: 'src/module/page2/main.js',
    template: 'src/module/page2/index.html',
    filename: 'page2/index.html'
  }
}

打包目录

1686891262146.jpg


相关文章
|
1月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
39 1
vue学习第一章
|
1月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
30 1
|
1月前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
38 1
vue学习第四章
|
1月前
|
JavaScript 前端开发 算法
vue学习第7章(循环)
欢迎来到瑞雨溪的博客,一名热爱JavaScript和Vue的大一学生。本文介绍了Vue中的v-for指令,包括遍历数组和对象、使用key以及数组的响应式方法等内容,并附有综合练习实例。关注我,将持续更新更多优质文章!🎉🎉🎉
25 1
vue学习第7章(循环)
|
1月前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
30 1
vue学习第九章(v-model)
|
1月前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
43 1
vue学习第十章(组件开发)
|
1月前
|
JavaScript 前端开发
vue学习第十一章(组件开发2)
欢迎来到我的博客,我是瑞雨溪,一名自学前端两年半的大一学生,专注于JavaScript与Vue。本文介绍Vue中的插槽(slot)使用方法,包括基本插槽、具名插槽及作用域插槽,帮助你在组件开发中实现内容的灵活定制。如果你觉得有帮助,请关注我,持续更新中!🎉🎉🎉
23 1
vue学习第十一章(组件开发2)
|
1月前
|
监控 JavaScript 前端开发
vue学习第十二章(生命周期)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。本文深入探讨了Vue实例的生命周期,从初始化到销毁各阶段的关键钩子函数及其应用场景,帮助你更好地理解Vue的工作原理。如果你觉得有帮助,欢迎关注我,将持续分享更多优质内容!🎉🎉🎉
29 1
vue学习第十二章(生命周期)
|
1月前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
1月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践