【Vue】全家桶之Vite

概述

Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 rollup 打包。

Vite 是一种新型前端构建工具,能够显著提升前端开发体验。它主要由两部分组成:

  • 一个开发服务器,基于原生 ES模块 提供了丰富的内建功能,如模块热更新(HMR);
  • 一套构建指令,使用 Rollup 打包你的代码,并且它是预配置的,可以输出用于生产环境的优化过的静态资源。

其特点就是:

  • 极速的服务启动:使用原生 ESM 文件,无需打包!
  • 轻量快速的热重载:无论应用程序大小如何,都始终极快的模块热重载(HMR)
  • 丰富的功能:对 TypeScript、JSX、CSS 等支持开箱即用。
  • 优化的构建:可选 “多页应用” 或 “库” 模式的预配置 Rollup 构建
  • 通用的插件:在开发和构建之间共享 Rollup-superset 插件接口。
  • 完全类型化的API:灵活的 API 和完整 TypeScript 类型。

搭建项目

Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。

使用 NPM:

$ npm create vite@latest

使用 Yarn:

$ yarn create vite

使用 PNPM:

$ pnpm create vite
然后按照提示操作即可!

你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Vite + Vue 项目,运行:

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

# npm 7+, extra double-dash is needed:
npm create 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

Vite 配置项

取别名

配置代理

环境变量

项目配置

预处理样式

直接安装 less/sass 即可使用,无需任何配置。

$ yarn add less -D
$ yarn add sass -D

移动端适配方案

安装依赖:

$ yarn add postcss-pxtorem autoprefixer -D

在根目录下创建 postcss.config.js 文件:

module.exports = {
    
    
  plugins: {
    
    
    autoprefixer: {
    
    
      overrideBrowserslist: [
        "Android 4.1",
        "iOS 7.1",
        "Chrome > 31",
        "ff > 31",
        "ie >= 8",
      ],
    },
    "postcss-pxtorem": {
    
    
      rootValue: 37.5, // Vant 官方根字体大小是 37.5
      propList: ["*"],
      selectorBlackList: [".norem"], // 过滤掉.norem-开头的class,不进行rem转换
    },
  },
};

新建 src/utils/rem.ts 文件:

// rem等比适配配置文件
// 基准大小,注意此值要与 postcss.config.js 文件中的 rootValue保持一致
const baseSize = 37.5;
// 设置 rem 函数
function setRem() {
    
    
  // 当前页面宽度相对于375宽的缩放比例,可根据自己需要修改,一般设计稿都是宽750(图方便可以拿到设计图后改过来)。
  const scale = document.documentElement.clientWidth / 375; // 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
  document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + "px";
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.onresize = function () {
    
    
  setRem();
};

在 mian.ts(x) 引入

import "./utils/rem"

提示:如果提示 “无法在 “–isolatedModules” 下编译“rem.ts”,因为它被视为全局脚本文件。请添加导入、导出或空的 “export {}” 语句来使它成为模块 ”此时你应该在 tsconfig.json 文件中将 isolatedModules 字段设置为 false。

全局TS类型声明

在根目录创建 typings/index.d.ts 文件

export {
    
    };

// => 全局类型声明
declare global {
    
    
  interface Window {
    
    
    _hmt: any;
    wx: any;
    AlipayJSBridge: any;
  }
  namespace GD {
    
    
    interface BaseResponse<T = any> {
    
    
      code: number;
      data: T;
      msg: string;
      page: {
    
    
        pageNo: number;
        pageSize: number;
        pages: number;
        total: number;
      };
    }
  }
}

提示:你需要在 tsconfig.json 文件里面的 include 字段中加入 [**/*.d.ts]。

然后就可以在全局访问了,如:

const response = GD.BaseResponse<{
    
    name: string}>

mock.js

①. 安装依赖:

$ yarn add mockjs -S
$ yarn add vite-plugin-mock -D

②. 引入插件 vite.config.js:

import {
    
     viteMockServe } from 'vite-plugin-mock';
export default defineConfig({
    
    
  plugins: [
    viteMockServe({
    
    })
  ],
});

③. 新建 mock/test.ts 文件

export default [
  {
    
    
    url: "/api-dev/users",
    method: "get",
    response: (req) => {
    
    
      return {
    
    
        code: 0,
        data: {
    
    
          name: "Li-HONGYAO",
          phone: "173 **** 8669",
          address: "成都市高新区雅和南四路216号",
        },
        msg: "success",
      };
    },
  },
];

④. 模拟请求

fetch("/api-dev/users")
  .then((res) => res.json())
  .then((users) => {
    
    
    console.log(users);
  });

动态加载静态资源

在使用 webpack 动态引入静态资源可以使用 require 形式,但是在vite中不可取,会抛出 require is not defined 的错误。
不过我们可以通过 import.meta.url 的形式引入,它是一个 ESM 的原生功能,会暴露当前模块的 URL。将它与原生的 URL 构造器 组合使用,在一个 JavaScript 模块中,通过相对路径我们就能得到一个被完整解析的静态资源 URL,其语法形式如下:

new URL(url, import.meta.url)

使用示例:

const imgs = [
  {
    
     imgUrl: new URL('./assets/logo_1.png', import.meta.url), text: "标题1" },
  {
    
     imgUrl: new URL('./assets/logo_2.png', import.meta.url), text: "标题2" },
];

值得注意的是,在生产环境中会抛出 “URL is not defined xxx” 的错误,这个时我们需要使用一个插件:rollup-plugin-import-meta-url-to-module。

使用方式比较简单,首先安装依赖:

$ yarn add rollup-plugin-import-meta-url-to-module

然后再 “vit.config.js” 中配置plugins:

import urlToModule from 'rollup-plugin-import-meta-url-to-module';

export default {
    
    
  plugins: [
    urlToModule()
  ]
};

vue配置

路由配置

安装依赖:

$ yarn add vue-router@next

在src下新建router目录,新建index.ts文件

import {
    
     createRouter, createWebHistory, RouteRecordRaw } from "vue-router";

const routes: Array<RouteRecordRaw> = [
  {
    
    
    path: "/",
    redirect: "/login",
  },
  {
    
    
    path: "/login",
    name: "login",
    component: () => import("pages/Login/Login.vue"),
    meta: {
    
    
      title: "登录",
    },
  },
  {
    
    
    path: "/index-page",
    name: "indexPage",
    component: () => import("pages/IndexPage/IndexPage.vue"),
    meta: {
    
    
      title: "首页",
    },
  },
];

const router = createRouter({
    
    
  history: createWebHistory(),
  routes,
});

// 导航守卫
router.beforeEach((to, from, next) => {
    
    
  if (to.path !== "/favicon.icon") {
    
    
    document.title = to.meta.title ? (to.meta.title as string) : "";
    next();
  }
});

export default router;

在main.ts挂载路由

import App from "./App.vue";
import router from "./router";

// App配置/挂载相关
// 1. 创建App
const app = createApp(App);
// 2. 注入
app.use(router);
// 3. 挂载
app.mount("#app");

状态管理

安装依赖:

$ yarn add vuex@next

配置:在src下创建store目录,并在store下创建index.ts

import {
    
     InjectionKey } from "vue";
import {
    
     createStore, ActionTree, GetterTree, MutationTree, Store } from "vuex";

// 1. 声明Store类型
declare interface StoreProps {
    
    
  authUrlForIos?: string;
}
// 2. 定义注入类型
export const globalStoreKey: InjectionKey<Store<StoreProps>> = Symbol();

// 3. ---- state
const state: StoreProps = {
    
    
  authUrlForIos: "",
};
// 3. ---- getters
const getters: GetterTree<StoreProps, any> = {
    
    
  authUrlForIos: (state) => state.authUrlForIos,
};
// 3. ---- mutations
const mutations: MutationTree<StoreProps> = {
    
    
  updateAuthUrlForIos(state, payload) {
    
    
    state.authUrlForIos = payload;
  },
};
// 3. ---- actions
const actions: ActionTree<StoreProps, any> = {
    
    
  updateAuthUrlForIos({
    
     commit }, payload) {
    
    
    commit("updateAuthUrlForIos", payload);
  },
};

// 4. 创建导出
export default createStore<StoreProps>({
    
    
  state,
  getters,
  mutations,
  actions,
});

挂载:在main.ts挂载数据中心

import App from "./App.vue";
import router from "./router";
import store, {
    
     globalStoreKey } from "./store";

// App配置/挂载相关
// 1. 创建App
const app = createApp(App);
// 2. 注入
app.use(router).use(store, globalStoreKey).use(vant);
// 3. 挂载
app.mount("#app");

二级目录部署

在同一个域名下部署多个项目的情况,我们就需要配置使用二级目录。

方案1:
打包时设置 -base 选项:

"build": "vue-tsc --noEmit && vite build --mode production --base=/二级目录名/",

然后再 router/index.ts 中配置如下:

const router = createRouter({
    
    
  // 部署二级目录:createWebHistory(base?: string)
  history: createWebHistory("/二级目录名/"),
  routes,
});

方案2:
在 vite.config.js 配置项中添加 base 配置,如:

base:"/YOUR_PROJECT_NAME/"

然后再 router/index.ts 中配置如下:

const router = createRouter({
    
    
  // 部署二级目录:createWebHistory(base?: string)
  history: createWebHistory("/二级目录名/"),
  routes,
});

来源

Vite 使用指南
vite官方中文文档

猜你喜欢

转载自blog.csdn.net/weixin_44231544/article/details/132297250