Vite3+Vue3+JavaScript:搭建企业级轻量框架实践(值得收藏)

4,034 阅读7分钟

483e90ffee64421d3e7b09a9d882bdfa.jpeg

引言

我看了这里好像还没有这方面的,大部分都是TS,如何你还没熟悉TS呢?怎么办。。。。。,还能怎么办,赶紧去把自己卷洗(我内心:卷不动了)。。。。哈哈哈哈😂。

这里面有几个大坑。。。。。稳稳的被我踩了

我们下面做了什么:

  • 使用vite 从零构建vue3的一个项目模版
  • 用eslint 做代码规范化
  • 用githook 来限制代码,如果不规范,不给commit
  • vite 配置UI库按需自动引入(相关其他的配置)
  • pinia 和 vuex哪个好,以及pinia的使用

接下来,为了让大家更好理解本项目工程化的思路,本文会按照以下关键词去逐步研读(看项目代码可跳过前4步)

script setup

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。

搞个简单demo对比script-setupscript区别:

// 单文件组件script-setup编写模式
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>
复制代码
// 普通script编写模式
<script>
import { ref } from 'vue'

export default {
    setup(props) {
      const count = ref(0)

      // 暴露给 template
      return {
        count
      }
    }
}
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>
复制代码

上述例子可以看出,script-setup弱化了vue模板式编程体验,也使得代码更简洁,开发者只需要引入正确的hooks后,把逻辑写在script内就足以。

本项目所有组件都采用这种开发模式,相比于普通的 <script> 语法,vue官方肯定了它的优势:

  • 更少的样板内容,更简洁的代码。
  • 能够使用纯 Typescript 声明 props 和抛出事件。
  • 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
  • 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)

最后笔者认为,从某方面讲Vue3是一次vue-hooks的革命,通过compositionApi的引用使组件写法更轻便简洁;而script-setup正好使得这种体验更加彻底,使单文件组件写法更接近函数式编程,在react和vue之间无缝切换。

Vite

Vite是一种新型前端构建工具,能够显著提升前端开发体验。比起webpack,vite还是有它很独特的优势,这里推荐一篇文章《Vite 的好与坏》给大家参考下。

项目为什么选vite代替webpack,结合社区和个人考虑,有几点:(具体就不展开,推文已经分析的很细致了)

  • Vite更加轻量,并且构建速度足够快
    webpack是使用nodejs去实现,而viite使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快不是一个数量级。
  • Vue官方出品,对vue项目兼容性不错
  • 发展势头迅猛,未来可期

当然事物都有两面性的,至目前为止,vite也有不少缺陷,例如:生态没有webpack成熟、生产环境下隐藏的不稳定因素等都是它如今要面临的问题。

但是,心怀梦想敢于向前,没有新势力的诞生,哪里来的技术发展?相比之下,vite更像一个青年,并逐步前行。

Pinia

Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎。它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库。

比起Vuex,Pinia具备以下优点:

  • 完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
  • 极其轻巧(体积约 1KB)
  • store 的 action 被调度为常规的函数调用,而不是使用 dispatch 方法或 MapAction 辅助函数,这在 Vuex 中很常见
  • 支持多个Store
  • 支持 Vue devtools、SSR 和 webpack 代码拆分 关于Pinia的进阶使用,笔者额外开了一篇专文介绍,有兴趣可以阅览:《Pinia进阶:优雅的setup(函数式)写法+封装到你的企业项目》\

工程化搭建

言归正传,我们通过以上技术,整合到一个项目中去。一般用于企业级生产的项目,要具备以下能力:

  • 容错性、可拓展性强
  • 组件高内聚,减少模块之间耦合度
  • 清晰的项目执行总线,方便增加插槽逻辑
  • 高度抽象的全局方法
  • 资源压缩+性能优化等

对照这些指标,我们来逐步搭建一个初步的工程框架。

备注:关于vue3语法、pinia使用等编程知识不会在这里细述了,大家可以到网上检索或者直接在项目里面寻找。

1. 技术栈

编程: Vue3.x + Jypescript
构建工具:Vite
路由 | 状态管理:vue-router + Pinia
UI Vant:vant

2. 工程结构

截屏2022-08-24 下午2.16.28.png

其中,src/utils里面放置全局方法,供整个工程范围的文件调用,当然工程初始化的事件总线也放在这里「下面会细述」。src/typessrc/constants分别存放项目的类型定义和常量,以页面结构来划分目录。

3. 工程配置

搭建Vite + Vue项目

#npm 6.x  
npm init vite@latest my-vue-app --template vue

#npm 7+, 需要额外的双横线:    
npm init vite@latest my-vue-app -- --template vue

#yarn   
yarn create vite my-vue-app --template vue

#pnpm   
pnpm create vite my-vue-app -- --template vue

4. 代码规范 配置

npm i eslint eslint-plugin-vue -D

  • package.json
"scripts":{
"lint:create": "eslint --init",
"lint": "eslint src/**/*.{js,vue} --fix ",
} 

  • npm run lint:create

  • 按照提示。 截屏2022-08-24 上午11.07.09.png 注意事项
    1、在项目根目录会生成.eslintrc.cjs 文件.
    2、npm run lint会报错,因为vite 生成的 的package.json 文件里面type=module,这样js文件的模式是es模式。解决如下:.eslintrc.js 改成 .eslintrc.cjs

5.限制开发者代码规范,才可以commit code

  • 你团队的成员就是把不规范的代码都提交了,你是想锤他了,你out shitp 了 🐻 der,我们可以限制必须规范代码才可以commit

1、npm i lint-staged -D

2、在package.json 文件里面加

"lint-staged": {
   "*.{js,jsx,vue}": [
     "npm run lint",
     "git add"
   ]
}
"gitHooks": {
   "pre-commit": "lint-staged"
 },

6. 配置vite.config.js

1、安装文件path 对象 ,用来重写src 别名。 在es 里面用的是 path-browserify

npm i path-browserify -D

2、安装 自动按需加载插件unplugin-vue-components

npm i unplugin-vue-components -D

3、vite 文件配置如下:(可以根据需要不同的UI框架来使用)

import { defineConfig } from 'vite';
import path from 'path-browserify'; //vite 写法 esm 模式
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],    // 按需加载vant 组件
    }),,
  ],
  base: './',
  // // 静态资源服务的文件夹,默认public
  publicDir: 'public',
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    },
  },

  css: {
    // 引入 autoprefixer
    postcss: {
      plugins: [
        // require('autoprefixer')
      ]
    },
    // 引入全局 scss
    preprocessorOptions: {
      scss: {
        additionalData: "@import './src/assets/styles/common.scss';"
      }
    }
  },
  server: {
    // 服务器主机名,如果允许外部访问,可设置为"0.0.0.0"
    host: '192.168.1.0',
    port: 8000, // 服务器端口号
    open: false, // 是否自动打开浏览器
    // 代理
    proxy: {
      '/api': {
        target: 'http://xxx.xxx.xx',
        changeOrigin: false
      }
    }
  }
});

4、使用组件

完成以上两步,就可以直接在模板中使用 Vant 组件了,unplugin-vue-components 会解析模板并自动注册对应的组件。

<template> 
    <van-button type="primary" />
</template>

5、 引入函数组件的样式

Vant 中有个别组件是以函数的形式提供的,包括 ToastDialogNotify 和 ImagePreview 组件。在使用函数组件时,unplugin-vue-components 无法自动引入对应的样式,因此需要手动引入样式。

import { Toast } from 'vant';
import 'vant/es/toast/style';

// Dialog
import { Dialog } from 'vant';
import 'vant/es/dialog/style';

// Notify
import { Notify } from 'vant';
import 'vant/es/notify/style';

// ImagePreview
import { ImagePreview } from 'vant';
import 'vant/es/image-preview/style';

7.批量导入路由文件

1、需求我们经常需要批量导入一些文件,做动态批量导入资源
2、vue2 之前就是用了webpackrequire.content来处理

在vite中批量导入 import { createRouter, createWebHashHistory } from 'vue-router' let metaRouters = import.meta.glob('../pages/*/route.js', { eager: true })

import { createRouter, createWebHashHistory } from 'vue-router'
let metaRouters = import.meta.glob('../pages/*/route.js', { eager: true })



let allrouter = []
Object.keys(metaRouters).forEach( item => {
  metaRouters[item].default.forEach(item => {
    allrouter.push(item)
  })
})

const Router = createRouter({
  history: createWebHashHistory(),
  routes: allrouter,
})


export default Router

注意import.meta.glob('../pages/*/route.js', { eager: true })如果没设置eager: true就是异步导入,这样没拿到就无法生成路由,配置就是同步一次性导入,类似require.content

结束语:前端技术真他么多。。。。。。。。。。。。。,躺平了