从零开始搭建前端项目五(vite.config.ts优化)

3,105 阅读4分钟

从零开始搭建前端项目五(vite.config.ts优化)

从零开始一步一步搭建一个精简的前端项目。

技术栈:Vue3.0 + Vite + TypeScript + Element Plus + Vue Router + axios + Pinia

规范化:Eslint + Airbnb JavaScript Style + husky + lint-staged

包管理:yarn

历史内容

从零开始搭建前端项目一(Vue3+Vite+TS+Eslint+Airbnb+prettier)

从零开始搭建前端项目二(husky+lint-staged)

从零开始搭建前端项目三(Element Plus)

从零开始搭建前端项目四(Vue Router)

本章内容

在项目中优化vite.config.ts配置,自动按需引入api、组件,启动优化,监听配置文件修改并重新加载页面。

自动按需引入

解决的问题:每次使用vuevue-routerpinia时,需要额外的import vue的api。比如使用ref时,需要先import { ref } from 'vue'。

使用效果如下:

ts12.png

安装

安装依赖,下面两个库在第三部分的时候已经安装过了。

yarn add unplugin-vue-components unplugin-auto-import --dev

配置

配置 vite.config.ts

// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite';        
import Components from 'unplugin-vue-components/vite';   

export default {
  plugins: [
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'],        // ++
      // 第三方组件库的解析器
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      // dirs 指定组件所在位置,默认为 src/components
      // 可以让我们使用自己定义组件的时候免去 import 的麻烦
      dirs: ['src/components/'],                     // ++
      // 配置需要将哪些后缀类型的文件进行自动按需引入
      extensions: ['vue'],                           // ++
      // 解析的 UI 组件库,这里以 Element Plus 为例
      resolvers: [ElementPlusResolver()],
    }),
  ],
}

TypeScript 报错

TypeScript 报错:找不到名称“ElMessage”,即找不到组件名称。这是因为我们生成的 auto-imports.d.tscomponents.d.ts 两个文件,默认是生成在项目根目录,正常我们配置的 TypeScript 解析的文件都放在 src 文件夹下。所以我们要将两个文件移动到src 文件夹下,并且在vite.config.ts中指定上述文件地址。

// vite.config.ts
export default {
  plugins: [
    AutoImport({
      dts: './src/auto-imports.d.ts',                 // ++
    }),
    Components({
      dts: './src/components.d.ts',                   // ++
    }),
  ],
}

Eslint 报错

Eslint 报错:'useRouter' is not defined. 即找不到引入的api。因为 Eslint 不知道我们按需引入的这些 api。所以需要在并且在vite.config.ts.eslintrc.js中配置。

// vite.config.ts
export default {
  plugins: [
    AutoImport({
      // Generate corresponding .eslintrc-auto-import.json file.
      // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
      eslintrc: {
        enabled: true, // Default `false`
        filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
        globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
      },
    }),
  ],
}

上述配置会在根目录下生成一个 .eslintrc-auto-import.json 文件,里面都是我们所引入的所有 API 名称

ts13.png

.eslintrc.js 中加载这个文件。

// .eslintrc.js
module.exports = { 
  extends: [
    // ...
    './.eslintrc-auto-import.json',            // ++
  ],
}

启动项目,没有报错。

启动优化

我们使用 Vite 开发项目时,第一次启动经常会看到命令行中出现:

new dependencies found: vue updating...

这个时间往往会耗时很久,而针对于这个情况,也有相对应的插件来解决这个问题。

安装

安装依赖

yarn add vite-plugin-optimize-persist vite-plugin-package-config --dev

配置

配置 vite.config.ts

// vite.config.ts
import OptimizationPersist from 'vite-plugin-optimize-persist'  // ++
import PkgConfig from 'vite-plugin-package-config'              // ++

export default {
  plugins: [
    // ...
    PkgConfig(),                                 // ++
    OptimizationPersist()                        // ++
  ],
}

这样配置完成后,我们第一次使用按需引入后,它就会在 package.json 中生成内容(生成的内容根据你项目所使用的组件而定),再次启动时可以快速启动项目。

ts14.png

重构vite.config.ts

这时候vite.config.ts里面的内容越来越多,我们将文件中plugins部分抽取出来单独放在一个文件中。在根目录下创建config文件夹。

ts15.png

其中constant.ts放入一些常量,vitePlugins.ts放入Vite使用的plugins。也可以每个plugins单独一个文件再合并,大家看自己项目使用的plugins数量决定。

将前面使用的plugins整理如下:

// vitePlugins.ts
import type { Plugin } from 'vite';
import vue from '@vitejs/plugin-vue';

import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import VueSetupExtend from 'vite-plugin-vue-setup-extend';
import OptimizationPersist from 'vite-plugin-optimize-persist';
import PkgConfig from 'vite-plugin-package-config';

import { ConfigEnv } from 'vite';

export default (env: ConfigEnv) => {
  const vitePlugins: (Plugin | Plugin[])[] = [
    vue({
      include: [/.vue$/],
    }),
    AutoImport({
      dts: './src/auto-imports.d.ts',
      imports: ['vue', 'vue-router'],
      // Generate corresponding .eslintrc-auto-import.json file.
      // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
      eslintrc: {
        enabled: true, // Default `false`
        filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
        globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
      },
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      dts: './src/components.d.ts',
      extensions: ['vue'],
      include: [/.vue$/, /.vue?vue/],
      // imports 指定组件所在位置,默认为 src/components; 有需要也可以加上 view 目录
      dirs: ['src/components/'],
      resolvers: [ElementPlusResolver({ importStyle: 'sass' })],
    }),
    VueSetupExtend(),
    PkgConfig(),
    OptimizationPersist(),
  ];
  return vitePlugins;
};

vite.config.ts中配置

import { defineConfig, loadEnv, ConfigEnv } from 'vite';
import { resolve } from 'path';
import vitePlugins from './config/vitePlugins';    // ++

import {
  VITE_PORT,
  VITE_DROP_CONSOLE,
  API_BASE_URL,
  API_TARGET_URL,
} from './config/constant';

export default defineConfig((env: ConfigEnv) => {
  const viteEnv = loadEnv(env.mode, `.env.${env.mode}`);
  return {
    base: viteEnv.VITE_BASE,
    plugins: vitePlugins(env),                   // ++
  };
});

监听配置文件

安装

我们在config文件夹下的constant.ts文件中定义了常量,在开发过程如果修改其中的值,项目需要自动加载。这时候我们需要vite-plugin-restart插件

yarn add vite-plugin-restart --dev

配置

vitePlugins.ts中配置

// vitePlugins.ts
const vitePlugins: (Plugin | Plugin[])[] = [
    // ...
    ViteRestart({
        // 配置监听的文件
        restart: ['*.config.[jt]s', '**/config/*.[jt]s'],    // ++
    }),
];

------ 2022.03.22 更新 ------

上述没有根本上将plugin配置抽取出来,还是写在了一个文件中,还是不够模块化。参考fast-vue3的写法,继续拆分plugin配置。创建vitePlugins文件夹,如图。

ts21.png

index.ts为入口文件,将文件夹下其他plugin配置组合起来。

// index.ts
import type { Plugin, ConfigEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import PkgConfig from 'vite-plugin-package-config';
import OptimizationPersist from 'vite-plugin-optimize-persist';
import VueSetupExtend from 'vite-plugin-vue-setup-extend';
import { AutoImportDeps } from './autoImport';
import { AutoRegistryComponents } from './component';
import { ConfigCompressPlugin } from './compress';
import { ConfigRestartPlugin } from './restart';
import { ConfigMockPlugin } from './mock';

export function createVitePlugins(env: ConfigEnv) {
  const isBuild = env.command === 'build';

  const vitePlugins: (Plugin | Plugin[])[] = [
    // vue支持
    vue({
      include: [/\.vue$/],
    }),
    // 自动按需引入组件
    AutoRegistryComponents(),
    // 自动按需引入依赖
    AutoImportDeps(),
    // 开启.gz压缩  rollup-plugin-gzip
    ConfigCompressPlugin(),
    VueSetupExtend(),
    // 监听配置文件改动重启
    ConfigRestartPlugin(),
    PkgConfig(),
    OptimizationPersist(),
  ];

  // vite-plugin-mock
  vitePlugins.push(ConfigMockPlugin(isBuild));

  return vitePlugins;
}

export default createVitePlugins;

例如自动按需引入组件。

// autoImport.ts
import AutoImport from 'unplugin-auto-import/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

export const AutoImportDeps = () => {
  return AutoImport({
    dts: 'src/auto-imports.d.ts',
    imports: ['vue', 'pinia', 'vue-router'],
    // Generate corresponding .eslintrc-auto-import.json file.
    // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
    eslintrc: {
      enabled: true, // Default `false`
      filepath: '../../.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
      globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
    },
    resolvers: [ElementPlusResolver()],
  });
};

export default AutoImportDeps;

这样每个plugin配置都在单独的文件中,修改的时候也只修改单个文件。

小结

本篇介绍了如何优化vite.config.ts配置,自动按需引入vue,vue-router,pinia的api、自动按需引入组件,启动项目优化速度,监听配置文件修改并重新加载页面。并将vite.config.ts的plugins单独抽取出来。

参考文章

几个插件,让你的Vue代码 “学会” 自动按需引入 - 掘金