vite2 常用插件篇(三)- 进阶插件

今日

身为中国人,恐怕没有不知道的,今天是七夕节,属于我们自己的情人节!

在读这篇文章的朋友,如果你已经有了另一半,那么恭喜你,祝愿你们度过一个浪漫温馨的七夕节。

没有的话,还是好好学习,再去赢取你心目中的白富美吧~

前言

我们在上一篇文章主要讲了vite日常开发的几个基础插件,这篇文章讲下另外几个常用的进阶插件

一、vite-plugin-windicss

1.说明

在Vite上单独使用Tailwind时,渲染速度很慢。

vite-plugin-windicssTailwind快20到100倍。

2.安装

yarn add vite-plugin-windicss --dev
复制代码

3.创建Windicss配置文件

(1)windicss的配置

(2)tailwind的配置

tailwind.config.ts

import lineClamp from 'windicss/plugin/line-clamp';
import colors from 'windicss/colors';

import { defineConfig } from 'vite-plugin-windicss';
import { primaryColor } from './build/config/themeConfig';

export default defineConfig({
  darkMode: 'class',
  plugins: [lineClamp, createEnterPlugin()],
  theme: {
    extend: {
      colors: {
        ...colors,
        primary: primaryColor,
      },
      screens: {
        sm: '576px',
        md: '768px',
        lg: '992px',
        xl: '1200px',
        '2xl': '1600px',
      },
    },
  },
});

/**
 * 用于元素显示时的动画
 * @param maxOutput 输出越大,生成的css体积越大
 */
function createEnterPlugin(maxOutput = 10) {
  const createCss = (index: number, d = 'x') => {
    const upd = d.toUpperCase();
    return {
      [`*> .enter-${d}:nth-child(${index})`]: {
        transform: `translate${upd}(50px)`,
      },
      [`*> .-enter-${d}:nth-child(${index})`]: {
        transform: `translate${upd}(-50px)`,
      },
      [`* > .enter-${d}:nth-child(${index}),* > .-enter-${d}:nth-child(${index})`]: {
        'z-index': `${10 - index}`,
        opacity: '0',
        animation: `enter-${d}-animation 0.4s ease-in-out 0.3s`,
        'animation-fill-mode': 'forwards',
        'animation-delay': `${(index * 1) / 10}s`,
      },
    };
  };
  const handler = ({ addBase }) => {
    const addRawCss = {};
    for (let index = 1; index < maxOutput; index++) {
      Object.assign(addRawCss, {
        ...createCss(index, 'x'),
        ...createCss(index, 'y'),
      });
    }
    addBase({
      ...addRawCss,
      [`@keyframes enter-x-animation`]: {
        to: {
          opacity: '1',
          transform: 'translateX(0)',
        },
      },
      [`@keyframes enter-y-animation`]: {
        to: {
          opacity: '1',
          transform: 'translateY(0)',
        },
      },
    });
  };
  return { handler };
}
复制代码

3.创建配置文件

build/vite/plugin/windicss.ts

import type { Plugin } from 'vite';

import windiCSS from 'vite-plugin-windicss';

export function configWindiCssPlugin(): Plugin[] {
  return windiCSS({
    safelist: 'no-select',
    preflight: {
      enableAll: true,
    },
  });
}
复制代码

4.应用配置

build/vite/plugin/index.ts

// ...
import { configWindiCssPlugin } from './windicss';

export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
  // ...
  // vite-plugin-windicss
  vitePlugins.push(configWindiCssPlugin());
  return vitePlugins;
}
复制代码

5.导入样式

src/main.ts

// ...
import '@virtual/windi.css';

// ...
复制代码

二、vite-plugin-mock

1.说明

vite-plugin-mock

根据我自己的试验:

  • localEnabled用来控制mock开发环境是否启动。
  • 如果生产环境想要使用mock,只有prodEnabled为true,injectCode注入指定代码时才会生效。

2.安装 mockjsvite-plugin-mock

# node version: >=12.0.0
# vite version: >=2.0.0

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

# 或者:

npm install mockjs -S
npm install vite-plugin-mock -D
复制代码

3.编写Mock用例

这里直接将根目录下的mock目录拷贝出来就行。

  • mock/_util.ts:里面封装的是数据请求结构类型。
  • mock\_createProductionServer.ts:用于配置生产环境动态Mock的js文件,文档中有说。
  • 其他的:都是Mock用例。每一个jsts。都要默认导出一个MockMethod类型的数组。每一项MockMethod就是拦截的一个方法。MockMethodresponse对应方法的return将会被Mock实例处理。也就是说,你可以在return的对象中使用Mock规则

不过_createProductionServer.ts中使用了Glob 导入

在根目录下新建两个文件:

mock/demo/user.ts

mock/_createMockServer.ts

user.ts:

import { MockMethod } from 'vite-plugin-mock';
export default [
  // mock userInfo
  {
    url: '/api/v1/userInfo',
    timeout: 200,
    method: 'get',
    response: ({ body }) => {
      console.log('body', body);
      return {
        code: 0,
        message: 'OK',
        data: {
          userName: 'admin',
          headThumb: 'http://xxx/avatars/profile.gif',
        },
      };
    },
  },
] as MockMethod[];
复制代码

_createMockServer.ts

经试验,这个mock文件名称最好这样命名,否则会有不可预料的错误

import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';

const modules = import.meta.globEager('./**/*.ts');

const mockModules: any[] = [];
Object.keys(modules).forEach((key) => {
  if (key.includes('/_')) {
    return;
  }
  mockModules.push(...modules[key].default);
});

/**
 * 在生产环境中使用。 需要手动导入所有模块
 */
export function setupProdMockServer() {
  createProdMockServer(mockModules);
}
复制代码

⚠️ 注意:此时 import.meta.globEager 可能会有类型错误提示:

mock-server-error.png

修改 tsconfig.json 配置的 include 属性就正常了:

  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "mock/**/*.ts" //++ 新增
  ]
复制代码

4.配置使用 vite-plugin-mock

build/vite/plugin/mock.ts

import { viteMockServe } from 'vite-plugin-mock';

export function configMockPlugin(isBuild: boolean) {
  return viteMockServe({
    // eslint-disable-next-line no-useless-escape
    ignore: /^\_/,
    mockPath: 'mock',
    localEnabled: !isBuild,
    prodEnabled: isBuild,
    injectCode: `
      import { setupProdMockServer } from '../mock/_createMockServer';

      setupProdMockServer();
      `,
  });
}
复制代码

5.配置进Vite

build/vite/plugin/index.ts

// ...
import { configMockPlugin } from './mock';

export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, pkg: any) {
  // ...
  const {
    VITE_USE_MOCK: shouldUseMock,
  } = viteEnv;
  // vite-plugin-mock
  shouldUseMock && vitePlugins.push(configMockPlugin(isBuild));

  return vitePlugins;
}
复制代码

6. 测试 mock

src 目录下新增:

api/user/index.ts

import http from '@/utils/http/index';
enum UserAPI {
  getUserInfo = '/api/v1/userInfo',
}

/**
 * 获取用户信息
 */
export async function getUserInfo(): Promise<any> {
  return http.get({
    url: UserAPI.getUserInfo,
  });
}
复制代码

src/views/demo/index.vue:

<template>
  <div>
    <div>demo</div>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive } from 'vue';
import { getUserInfo as getUserInfoApi } from '@/api/user/index';

export default defineComponent({
  setup() {
    // ------------------------------------------ reactive ------------------------------------------

    const getUserInfo = async () => {
      try {
        const result = await getUserInfoApi();
        if (result && result.code === 0 && result.data) {
          console.log(result.data);
        }
      } catch (error) {
        console.log('error', error);
      }
    };
    onMounted(() => {
      getUserInfo();
    });
    return {
      userInfo,
    };
  },
});
</script>

<style lang="scss">
</style>

复制代码

终端效果如下

vite-mock.png

说明 mock 是成功的

三、vite-plugin-purge-icons

1.说明

这个插件是可以让我们很方便高效的使用Iconify中所有的图标。

这里要讲的是Iconify各个版本插件的区别:

  • Vue3版Iconify插件:使用时需要安装指定库的图标,然后静态引用。每一次引用都会产生一次http请求。
  • PurgeIcons:将我们所使用的Iconify图标都已htmldom节点形式保存在html中,这样我们就可以不发送http请求就可以使用图标了。
  • vite-plugin-purge-icons:就是Vite版的PurgeIcons

2.安装

yarn add @iconify/iconify
yarn add vite-plugin-purge-icons @iconify/json --dev
复制代码

3.配置Vite

build/vite/plugin/index.ts

// ...
import PurgeIcons from 'vite-plugin-purge-icons';

export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
  // ...
  // vite-plugin-purge-icons
  vitePlugins.push(PurgeIcons({
      /* PurgeIcons Options */
  }));

  // ...
  return vitePlugins;
}
复制代码

4.main中导入

src/main.ts

import { createApp } from 'vue'
import App from './App.vue'

// 导入 icons
import '@purge-icons/generated'

createApp(App).mount('#app')
复制代码

六、rollup-plugin-visualizer

1.说明

2.安装visualizer

yarn add rollup-plugin-visualizer @types/rollup-plugin-visualizer --dev
复制代码

3.配置插件

build/vite/plugin/visualizer.ts

/**
 * 包文件体积分析
 */
import visualizer from 'rollup-plugin-visualizer';
import { isReportMode } from '../../utils';
import type { Plugin } from 'vite';

export function configVisualizerConfig() {
  if (isReportMode()) {
    return visualizer({
      filename: './node_modules/.cache/visualizer/stats.html',
      open: true,
      gzipSize: true,
      brotliSize: true,
    }) as Plugin;
  }
  return [];
}
复制代码

4.配置Vite

build/vite/plugin/index.ts

// ...
import { configVisualizerConfig } from './visualizer';

export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, pkg: any) {
  // ...
  // rollup-plugin-visualizer
  vitePlugins.push(configVisualizerConfig());

  return vitePlugins;
}
复制代码

5.安装cross-env

yarn add cross-env --dev
复制代码

6.添加脚本

package.json

{
  // ...
  "scripts": {
    // ...
    "report": "cross-env REPORT=true npm run build"
    // ...
  }
  // ...
}
复制代码

7. 执行脚本查看报告

npm run report
复制代码

生成报告后会自动打开浏览器,就像下面这样 ??

vite-visualizer.png

很明显可以看出来哪些依赖包占用体积最大,接下来就可以根据项目情况来优化下项目体积啦~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享