前端框架:vite2+vue3+typescript+axios+vant移动端 框架实战项目详解(一)

2,146 阅读12分钟

☞本系列文章过长会分开消化理解:

📚本系列文涉及技术及知识点

  • 1、vite2.x
  • 2、vue3.2.x
  • 3、typescript
  • 4、vuex (状态管理 pinia也可以使用) 创建方式:new Vuex.Store(...)(vuex3),createStore(...)(vuex4)。
  • 5、vue router 4.x
  • 6、axios封装
  • 7、移动端样式适配
  • 8、vant组件库使用
  • 9、环境变量配置
  • 10、scss
  • 11、rem

ps:还会有一些问题的或者创建框架时遇到问题的总结及解答

☞技术知识点的了解:vite

❓vite是个啥

官方网站:vitejs.cn/guide/。

vite(法语意为 "快速的",发音 /vit/img,发音同 "veet"),是一个开发构建工具,能够显著提升前端开发体验。 开发过程中它利用浏览器native ES Module特性导入组织代码,生产中利用rollup作为打包工具。它有如下特点:

  • 光速启动、冷服务启动
  • 热模块替换、开发中热更新
  • 按需编译、不会刷新全部DOM
问答时间:

🙋‍问: 1、可能有人会问vite是一个开发构建工具,那生产环境怎么办?

答:它会使用 Rollup 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。

🙋‍问: 2、开发过程中它利用浏览器native ES Module特性导入组织代码是什么意思?

答:是指面向现代浏览器,基于原生模块系统Module实现,这比webpack的开发环境快,因webpack开发时需要进行编译放到内存中。

总结:

其实vite就是为开发者量身定做的一套先进的开发工具,按需编译、热模块替换等特性使我们开发时免除了重新打包的等待时间,开发体验丝滑,默认还整合了vue3。目前vite已经是正式版,相关的生态正在迅速繁荣起来。

🧩vite2构建工具优缺点

传统工具开发环境构建方式和vite对比

传统工具构建方式:

image.png vite 构建方式:

image.png

1、我们可以看到:

  • 传统工具构建方式:当冷启动开发服务器时,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。
  • vite:通过在一开始将应用中的模块区分为依赖和源码两类,改进了开发服务器启动时间。
vite改进
  • Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。
  • 依赖 大多为纯 JavaScript 并在开发时不会变动。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模块中。
  • Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。
  • 源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载。(例如基于路由拆分的代码模块)。
  • Vite 以 原生 ESM 方式服务源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入的代码,即只在当前屏幕上实际使用时才会被处理。

2、构建不同

  • 传统工具构建方式:使用的是node.js去实现
  • Vite 将会使用 esbuild 预构建依赖。
vite改进
  • Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 Node.js 编写的打包器预构建依赖快 10-100 倍。

3、热更新效率

  • 传统工具构建方式: 当基于打包器启动时,编辑文件后将重新构建文件本身。显然我们不应该重新构建整个包,因为这样更新速度会随着应用体积增长而直线下降。

一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活,但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而对页面其余部分没有影响。这大大改进了开发体验 - 然而,在实践中我们发现,即使是 HMR 更新速度也会随着应用规模的增长而显著下降。

  • vite改进
    • 在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失效(大多数时候只需要模块本身),使 HMR 更新始终快速,无论应用的大小
    • Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。

优缺点

Vite 优点Vite 缺点
开发服务器比 Webpack 快 10-100 倍只能针对现代浏览器(ES2015+)
将 code-splitting 作为优先事项与 CommonJS 模块不完全兼容
最小的脚手架不包括 Vuex、路由器等
不同的开发服务器与构建工具
生态不如webpack
prod环境的构建,目前用的Rollup(原因在于esbuild对于css和代码分割不是很友好)
还没有被大规模使用,很多问题或者诉求没有真正暴露出来

vite缓存

文件系统缓存

Vite 会将预构建的依赖缓存到 node_modules/.vite。它根据几个源来决定是否需要重新运行预构建步骤:

  1. package.json 中的 dependencies 列表
  2. 包管理器的 lockfile,例如 package-lock.json, yarn.lock,或者 pnpm-lock.yaml
  3. 可能在 vite.config.js 相关字段中配置过的

只有当上面的一个步骤发生变化时,才需要重新运行预构建步骤。

问答时间

🙋‍问: 如果想要强制 Vite 重新绑定依赖,怎么办呢?

答:你可以用 --force 命令行选项启动开发服务器,或者手动删除 node_modules/.vite 目录。

浏览器缓存

解析后的依赖请求会以 HTTP 头 max-age=31536000,immutable 强缓存,以提高在开发时的页面重载性能。一旦被缓存,这些请求将永远不会再到达开发服务器。如果安装了不同的版本(这反映在包管理器的 lockfile 中),则附加的版本 query 会自动使它们失效。

问答时间

🙋‍问: 如果想通过本地编辑来调试依赖项,怎么办呢?

答:如下步骤:

  1. 通过浏览器 devtools 的 Network 选项卡暂时禁用缓存;
  2. 重启 Vite dev server,使用 --force 标志重新打包依赖;
  3. 重新载入页面。

⚙使用

1、兼容性了解

Vite 需要 Node.js 版本 >= 12.0.0。

node -v 可查看版本号,下边是本小编的node.js的版本

image.png

ps:建议使用vscode并且安装volar,安装volar一定关闭vetur,否则会有冲突

image.png

2、vite创建项目

第一种: npm init初始化项目时安装 Vite

#npm 6.x

npm init @vitejs/app <project-name> --template

#npm 7+, 需要额外的双横线:

npm init @vitejs/app <project-name> -- --template

#yarn

yarn create @vitejs/app <project-name> --template

#pnpm

pnpm create vite <project-name> -- --template vue

npm -v 可查看npm版本号,下边是本小编的npm的版本

image.png

在select a framework 时我们可以看到 时可以选择不同的框架的,如果你的没有 select a framework 直接是 select a variant 那就直接选vue-ts (因为本文是需要讲typescripts),如果不想使用ts可以直接选用vue

image.png

image.png

#如果不想选择,可任意使用快速命令

npm init @vitejs/app <project-name> --template vue-ts

继续:

  cd <project-name>
  npm install
  npm run dev

第二种:我们可以使用 create-vite-app先独立安装 Vite

npm install create-vite-app -g
create-vite-app <project-name>
cd <project-name>
npm install
npm run dev

第三种:使用开源模板fast-vue3

最近,尤大为了让更多的小伙伴快速进入vue3,在Github发起了一个开源模板fast-vue3,以提供开箱即用的脚手架,快速渡过一档起步(各种配置),直接体验加速阶段(实际项目)。fast-vue3,是Vue3+Vite2.7+TypeScript+Pinia等Vue的开发工具链。整理了当前比较主流的工具链,可以直接开箱使用,方便小伙伴学习,最好的学习方式——边用边学边学边用~

image.png

特点:

  • fast-vue3就不赘述了,框架基座支持Vue3+Vite2.7+TypeScript+Pinia
  • 支持huskylint-staged,大厂团队代码规范协作必备
  • ️ 支持svg图标,已封装一个简单的SvgIcon组件,可以直接读取文件下的svg
  • 支持Plop,代码文件自动生成,提供三种预设模板pages,components,store等可自定义
  • 支持axios(ts版),已封装了主流的拦截器,请求调用等方法
  • 支持router,store模块化,内置生成路由钩子
  • 支持env,环境变量和区分打包环境
  • 支持unplugin-vue-components组件自动引入
  • 支持vw/vh移动端布局兼容,也可以使用plop自己配置生成文件
  • 支持vite-plugin-mdmarkdown渲染
  • 支持vite-plugin-pages根据文件自动生成路由的插件
git clone  https://github.com/MaleWeb/fast-vue3.git
cd fast-vue3 
pnpm install
pnpm run dev

也可以是 使用template分支进行项目开发,该分支不含任何示例代码

git clone -b template https://github.com/MaleWeb/fast-vue3.git

⛑注意:

我们在安装时项目时,如果使用npm 就一直使用npm ;如果使用pnpm 就一直使用pnpm;或者其他的安装,但是要保持整体的一致性,不然会有包的版本错误;(也包括后续的安装其他依赖)

问答时间:

🙋‍问:为什么不能网络访问呢?只有http://localhost:3000/

答: 我们可以看到 npm run dev 后边有一行: Network: use--host` to expose,这个就是用于网络访问

image.png

第一种方法:在package.json中加入--host 0.0.0.0

 "scripts": {
    "dev": "vite --host 0.0.0.0",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
  }

image.png

第二种方法:在vite.config.ts中加入--host 0.0.0.0

export default defineConfig({
  plugins: [vue()],
  server: {
    host: "0.0.0.0" // 解决  Network: use --host to expose
  }
})

image.png

image.png

3、vite创建代码简单分析

3.1、可以看到index.html中的入口文件导入方式 type="module"

image.png

3.2、框架代码中main.ts中就可以使用ES6 Module方式组织代码

image.png

我们在看看浏览器中加载的main.ts的代码是什么样的:

image.png

ps: 上边的整个过程是:

  • 1、其实当我们在index.html中声明一个 script 标签类型为 module 时,浏览器就会像服务器发起一个GET;
  • 2、浏览器请求到了main.js文件,检测到内部含有import引入的包,又会对其内部的 import 引用发起 HTTP 请求获取模块的内容文件;
  • 3、Vite 的主要功能就是通过劫持浏览器的这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器,vite整个过程中没有对文件进行打包编译,所以其运行速度比原始的webpack开发编译速度快出许多!

我们可以看到,浏览器会自动加载这些导入,vite会启动一个本地服务器处理不同这些加载请求,对于相对地址的导入,要根据后缀名处理文件内容并返回,对于裸模块导入要修改它的路径为相对地址并再次请求处理。

当然vite1.x中可以看到的是

import { createApp } from "/@modules/vue.js"
3.3 defineConfig可规范类型
import { defineConfig } from 'vite'

export default defineConfig({
 // ...
})

或者

export default ({ command, mode }) => {
  if (command === 'serve') {
    return {
      // serve specific config
    }
  } else {
    return {
      // build specific config
    }
  }
}
3.4 css文件
  • vite中可以直接导入.css文件,样式将影响导入的页面,最终会被打包到style.css

  • 在我们程序中,除了全局样式大部分样式都是以形式存在于SFC中

    Scoped CSS

    <style scoped>
    /**/
    </style>
    

    CSS Module

    <style module>
    
    </style>
       ```
    
3.5 vue文件结构发生变化

🎩我们可以看到.vue中的内容的顺序 script 、 template、style

script 默认放在页面的顶部,而试图放在了script 的下边,style放到页面的底部

image.png

☞☞另外,导入vue文件必须写上文件后缀名.vue,否则ts无法识别vue文件

4、vite2的变化

  • 配置选项变化:vue特有选项、引入方式变化、在安装的时候我们看到了:创建选型、css选项、jsx选项等;
  • 别名变化:不再要求/开头或结尾
  • vue支持:通过@vitejs/plugin-vue 单独插件支持
  • react支持
  • HMR api变化
  • 清单格式变化
  • 插件api重新设计

5、vite配置

更多详细vite配置的可参考官网:vitejs.cn/config/

5.1 别名配置

在vite.config.ts中加入

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import {resolve} from "path"// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      "@": resolve(__dirname,"src"),
      "comps": resolve(__dirname,"src/components"),
      "apis": resolve(__dirname,"src/apis"),
      "views": resolve(__dirname,"src/views"),
      "utils": resolve(__dirname,"src/utils"),
      "routes": resolve(__dirname,"src/routes"),
      "styles": resolve(__dirname,"src/styles"),
    },
  },
  
  plugins: [vue()],
  server: {
    host: "0.0.0.0" // 解决  Network: use --host to expose
  }
})
​

可以看到别名配置时,去掉了/

☞ps:我们想在.vue中的ts区域使用别名@

还需要配置ts.config.json

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "baseUrl": ".",
    "paths": {
      "@/*":["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "exclude": ["node_modules"]
}
5.2 css配置
css: {
      postcss:'', //内联的 PostCSS 配置(格式同 postcss.config.js),或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。
      preprocessorOptions: { // 指定传递给 CSS 预处理器的选项
        scss: {
          // 全局的scss ,跨域放多个,例如:主题的变量,和一些混合等
          // additionalData: `@import "src/styles/index.scss";`,
          javascriptEnabled: true,
        },
      },
    },
5.3 一些打包配置 :esbuild
问答时间:

🙋‍问:为什么我的vite.config.ts不能直接引用path模块

image.png

答: 我们需要安装模块依赖 npm install @types/node --save-dev