vite.config开发经验分享

发布时间 2023-11-29 11:11:03作者: 柯基与佩奇

前言

在使用 vue3 + vite 实际开发过程中的一些经验分享,涵盖 vite 构建优化配置项的实践,以及打包配置性能优化的实践

plugin 项目优化汇总

@vitejs/plugin-vue

vite 支持 vue 开发

按需引入组件库 unplugin-vue-components

unplugin-vue-components 插件可以在 Vue 文件中自动引入组件(包括项目自身的组件和各种组件库中的组件)作者是 Vite 生态圈大名鼎鼎的 Anthony Fu。使用此插件后,不需要手动编写  import { Button } from 'vant'这样的代码了,插件会自动识别  template中使用的自定义组件并自动注册。

unplugin-vue-components 是由 Vue 官方人员开发的一款自动引入插件,可以省去比如 UI 库的大量 import 语句。

// 1、安装
npm i unplugin-vue-components -D

// 2、配置
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    Components({
      dts: true,
      // dirs: ['src/components'], // 配置需要默认导入的自定义组件文件夹,该文件夹下的所有组件都会自动import;
      resolvers: [ElementPlusResolver()]
    }),
  ]
}

// 3、配置tsconfig.json
{
  // ...
  "include": ["./components.d.ts"]
}

// 插件的所有默认配置
Components({
  // relative paths to the directory to search for components.
  // 要搜索组件的目录的相对路径
  dirs: ["src/components"],
  // valid file extensions for components.
  // 组件的有效文件扩展名。
  extensions: ["vue"],
  // search for subdirectories
  // 搜索子目录
  deep: true,
  // resolvers for custom components
  // 自定义组件的解析器
  resolvers: [],
  // generate `components.d.ts` global declarations,
  // also accepts a path for custom filename
  // 生成 `components.d.ts` 全局声明,
  // 也接受自定义文件名的路径
  dts: false,
  // Allow subdirectories as namespace prefix for components.
  // 允许子目录作为组件的命名空间前缀。
  directoryAsNamespace: false,
  // 忽略命名空间前缀的子目录路径
  // 当`directoryAsNamespace: true` 时有效
  // Subdirectory paths for ignoring namespace prefixes
  // works when `directoryAsNamespace: true` globalNamespaces: [],
  // auto import for directives
  // default: `true` for Vue 3, `false` for Vue 2
  // Babel is needed to do the transformation for Vue 2, it's disabled by default for performance concerns.
  // To install Babel, run: `npm install -D @babel/parser @babel/traverse`
  // 自动导入指令
  // 默认值:Vue 3 的`true`,Vue 2 的`false`
  // 需要 Babel 来为 Vue 2 进行转换,出于性能考虑,它默认处于禁用状态。
  directives: true,
  // filters for transforming targets
  include: [/.vue$/, /.vue?vue/],
  exclude: [/[\/]node_modules[\/]/, /[\/].git[\/]/, /[\/].nuxt[\/]/],
});

unplugin-auto-import 的使用

unplugin-auto-import 为 Vite、Webpack、Rollup 和 esbuild 按需自动导入 API,支持 TypeScript

这个插件是为了解决在开发中的导入问题,比如经常不清楚相对路径的问题,这个插件就是解决这个问题。这个插件会在根目录生成一个 auto-import.d.ts,这个文件会将所有的插件导入到 global 中,这样在使用的时候直接就可以使用了

效果

// 引入前
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);

//引入后
const count = ref(0);
const doubled = computed(() => count.value * 2);

// 引入前
import { useState } from "react";
export function Counter() {
  const [count, setCount] = useState(0);
  return <div>{count}</div>;
}

//引入后
export function Counter() {
  const [count, setCount] = useState(0);
  return <div>{count}</div>;
}

使用

// 1、安装
npm i unplugin-vue-components -D

// 2、配置文件vite.config.ts
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    AutoImport({
      dts: 'types/auto-imports.d.ts', // 生成配置文件,如果是ts项目,通常我们会把声明文件放在根目录/types中,
      // 注意,这个文件夹需要先建好,否则可能导致等下无法往里生成auto-imports.d.ts文件
      imports: ['vue', 'vue-router', 'pinia'],
      resolvers: [ElementPlusResolver()],
      eslintrc: {
        enabled: false, // 默认false, true启用。生成一次就可以,避免每次工程启动都生成,一旦生成配置文件之后,最好把enable关掉,即改成false
        //否则这个文件每次会在重新加载的时候重新生成,这会导致eslint有时会找不到这个文件。当需要更新配置文件的时候,再重新打开
        filepath: './.eslintrc-auto-import.json', // 生成json文件,可以不配置该项,默认就是将生成在根目录
        globalsPropValue: true,
      },
    })
  ]
})

// 3、添加.eslintrc-auto-import.json
{
  "globals": {}
}
// 4、配置.eslintrc
{
  ...
  "extends": [
    ...
    "./.eslintrc-auto-import.json"
  ]
}
// 5、配置tsconfig.json
{
  ...
  "include": ["./auto-imports.d.ts"]
}

vite-plugin-style-import 使用

当使用 unplugin-vue-components 来引入 ui 库的时候,message, notification 等引入样式不生效。此时就需要安装 vite-plugin-style-import 即可

// vite.config.js
import { defineConfig } from "vite";
import styleImport, {
  AndDesignVueResolve,
  VantResolve,
  ElementPlusResolve,
  NutuiResolve,
  AntdResolve,
} from "vite-plugin-style-import";

export default defineConfig({
  plugins: [
    styleImport({
      resolves: [
        AndDesignVueResolve(),
        VantResolve(),
        ElementPlusResolve(),
        NutuiResolve(),
        AntdResolve(),
      ],
      // 自定义规则
      libs: [
        {
          libraryName: "ant-design-vue",
          esModule: true,
          resolveStyle: (name) => {
            return `ant-design-vue/es/${name}/style/index`;
          },
        },
      ],
    }),
  ],
  // 引用使用less的库要配置一下
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
});

jsx/tsx 语法支持 @vitejs/plugin-vue-jsx

此插件支持在 vue3 中使用 jsx/tsx 语法

npm i @vitejs/plugin-vue-jsx -D

vite.config.ts

import { defineConfig, loadEnv } from "vite";
import vuejsx from "@vitejs/plugin-vue-jsx";
export default ({ mode }) =>
  defineConfig({
    plugins: [vuejsx()],
  });

jsx 文件: (jsx 组件中自动跳过生命周期,即 jsx 中没有生命周期,在父组件 onBeforeMount 后执行)

const component = (props: any, context: any) => {
  console.log(props);
  const onClick = () => {
    context.emit("update");
  };
  return (
    <div
      style={{
        fontSize: 12,
        color: "#999",
      }}
      onClick={() => onClick()}
    >
      我是jsx函数组件{props.text}
    </div>
  );
};

export default component;

移动端 vconsole vite-plugin-vconsole

帮助开发者在各个环境下方便使用 VConsole 的功能。可以方便配置区分环境,根据环境动态加载 VConsole,支持多页面配置。

// 安装
npm i vite-plugin-vconsole -D

// tips: 如果引用path提示不存在,可以引入@types/node包
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { viteVConsole } from 'vite-plugin-vconsole';
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
  console.log(mode)
  const config: UserConfig = {
    plugins: [
      vue(),
      viteVConsole({
        entry: resolve('src/main.ts'), // 或者可以使用这个配置: [path.resolve('src/main.ts')]
        enabled: mode !== 'production', // 可自行结合 mode 和 command 进行判断
        config: {
          maxLogNumber: 1000,
          theme: 'dark'
        }
      })
    ],
  }
  return config
})

svg 作为组件使用 [vite-plugin-svg-icons]

方便在项目中使用 .svg 文件

//1、 安装:
npm i vite-plugin-svg-icons -D

//2、 vite.config.js配置
import { defineConfig,loadEnv } from 'vite'
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons';
const path = require("path");
export default  ({ mode }) => defineConfig({
  plugins: [
    vue(),
    createSvgIconsPlugin({
   		// 指定要缓存的文件夹
      iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
      // 指定symbolId格式
      symbolId: 'icon-[dir]-[name]'
    })
  ]
})
//3、main.js添加
import 'virtual:svg-icons-register'
//4、模块中使用
<svg style="width: 30px; height: 30px" fill="red">
    <use xlink:href="#icon-order" fill="blue"></use>
  </svg>


// 更多配置说明
viteSvgIcons({
  // 指定图标文件夹,数组形式,可以有多个
  iconDirs: [path.resolve(process.cwd(), 'icons')],
  // 指定symbolId格式
  symbolId: 'icon-[dir]-[name]',

  // 自定义插入位置
  inject?: 'body-last' | 'body-first',

  // 设置图标样式类名
  className?: 'svg-icon',

  // 设置svg元素属性
  svgoOptions: {},

  // 指定标题内容
  title?: false,

  // 生成sprite
  svgSprite: false,

  // 导入图标接口
  runtimeIconImport: 'import-all' | 'async',
})

封装组件,新建 SvgIcon.vue

SvgIcon.vue 可结合unplugin-vue-components 放置在src/components下,做自动引入

<!-- 页面中使用 -->
<svg-icon name="order" class="icon"></svg-icon>
<template>
  <svg
    aria-hidden="true"
    class="svg-icon"
    :fill="props.color"
    :width="width"
    :height="height"
  >
    <use :xlink:href="symbolId" />
  </svg>
</template>

<script setup name="svg-icon">
//  import { computed } from 'vue'
const props = defineProps({
  prefix: {
    type: String,
    default: "icon",
  },
  name: {
    type: String,
    required: true,
  },
  size: {
    type: String,
    default: "1em",
  },
  width: {
    type: String,
  },
  height: {
    type: String,
  },
  color: {
    type: String,
    default: "currentColor",
  },
});
const symbolId = computed(() => `#${props.prefix}-${props.name}`);
const width = computed(() => (props.width ? props.width : props.size));
const height = computed(() => (props.height ? props.height : props.size));
</script>

<style scope>
.svg-icon {
  fill: currentColor;
  outline: none;
  font-size: 14px;
}
</style>

自适应 px 转 vw postcss-px-to-viewport-8-plugin

// 安装
npm install postcss-px-to-viewport-8-plugin -D
// vite.config.js 配置

import { defineConfig } from 'vite'
import pxtovw from 'postcss-px-to-viewport-8-plugin'

export default defineConfig({
    css: {
      postcss: {
        plugins: [
          // 执行插件px转vw
          pxtovw({
            unitToConvert: 'px', // 需要转换的单位,默认为"px"
            viewportWidth: 375, // 设计稿的视口宽度
            viewportUnit: 'vw' // 希望使用的视口单位
            unitPrecision: 5, // 单位转换后保留的精度
            propList: ['*'], // 能转化为vw的属性列表
            fontViewportUnit: 'vw', // 字体使用的视口单位
            selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
            minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
            mediaQuery: false, // 媒体查询里的单位是否需要转换单位
            replace: true, //  是否直接更换属性值,而不添加备用属性
            exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
            include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
            landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
            landscapeUnit: 'vw', // 横屏时使用的单位
            landscapeWidth: 1920 // 横屏时使用的视口宽度
          })
        ]
      }
    }
})

打包分析插件 rollup-plugin-visualizer

打包后,会在根目录下生成一个 stats.html 文件

// 安装
npm install rollup-plugin-visualizer -D

// vite.config.js 配置
import { defineConfig } from 'vite'
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
    plugins: [visualizer()]
})

文件资源 vite-plugin-compression

使用 gzip 或者 brotli 来压缩资源

// 安装
npm i vite-plugin-compression -D

// vite.config.ts
import { defineConfig,loadEnv} from 'vite'
import viteCompression from 'vite-plugin-compression';
export default  ({ mode }) => defineConfig({
  plugins: [
    viteCompression()
  ]
})

图片资源压缩 vite-plugin-imagemin

npm i vite-plugin-imagemin -D
// vite.config.ts
import { defineConfig} from 'vite'
import viteImagemin from 'vite-plugin-imagemin'
export default  ({ mode }) => defineConfig({
  plugins: [
    viteImagemin({
      gifsicle: {
        optimizationLevel: 7,
        interlaced: false
      },
      optipng: {
        optimizationLevel: 7
      },
      mozjpeg: {
        quality: 20
      },
      pngquant: {
        quality: [0.8, 0.9],
        speed: 4
      },
      svgo: {
        plugins: [
          {
            name: 'removeViewBox'
          },
          {
            name: 'removeEmptyAttrs',
            active: false
          }
        ]
      }
    })
  ]
})

自动导入图片 vite-plugin-vue-images

自动导入图像,同级目录的文件名不能重复!

npm i vite-plugin-vue-images -D

import { defineConfig,loadEnv} from 'vite'
import ViteImages from 'vite-plugin-vue-images'
export default  ({ mode }) => defineConfig({
  plugins: [
    ViteImages({
      dirs: ['src/assets'], // 图像目录的相对路径
      extensions: ['jpg', 'jpeg', 'png', 'svg', 'webp'], // 有效的图像扩展
      customResolvers:[], // 覆盖名称->图像路径解析的默认行为
      customSearchRegex: '([a-zA-Z0-9]+)', // 重写搜索要替换的变量的Regex。
    }),
  ]

假设有以下文件及路径

logo.png: src/assets/logo.png

name1.jpg: src/assets/test/name1.jpg

使用方式:

<template>
  <div class="home">
    <img :src="Logo" />
    <img :src="TestName1" />
  </div>
</template>

<script setup lang="ts"></script>

<style lang="less" scoped></style>

插件将转换为:

<template>
  <div class="home">
    <img :src="Logo" />
    <img :src="TestName1" />
  </div>
</template>

<script setup lang="ts">
import Logo from "@/assets/logo.png";
import TestName1 from "@/assets/test/name1.jpg";
</script>

<style lang="less" scoped></style>

CDN 加速

使用 CDN 未必会加快速度,只能减小打包体积,因为对应 js 和 css 需要从远程地址读取

方案一:(推荐)使用 CDN 管理插件vite-plugin-cdn-import

npm install vite-plugin-cdn-import --save-dev

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 文档的用法会报错, 要这样引入才可以
import { autoComplete, Plugin as importToCDN } from 'vite-plugin-cdn-import';

export default defineConfig({
  plugins: [vue(),
   importToCDN({
    prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
    modules: [
      autoComplete('vue'),
      autoComplete('axios'),
      {
        name: 'element-plus',
        var: 'ElementPlus', //根据main.js中定义的来
        version: '2.2.17',
        path: 'dist/index.full.js',
        css: 'dist/index.css'
      },
      {
        name: '@element-plus/icons-vue',
        var: 'ElementPlusIconsVue', //根据main.js中定义的来
        version: '2.0.9',
        path: 'dist/index.iife.min.js'
      },
    ],
  })
],
})

方法二: rollup 的 external 功能结合插件 rollup-plugin-external-globals

// 安装
npm install rollup-plugin-external-globals -D

// vite.config.ts
import externalGlobals from 'rollup-plugin-external-globals';
const globals = externalGlobals({
  axios: 'axios'
});

export default defineConfig({
    build: {
        rollupOptions: {
            external: ['axios'],
            plugins: [globals],
        }
    }
})

// 在 index.html 模版中引入对应库的CDN。或者使用插件vite-plugin-html
<script src="https://unpkg.com/axios@1.5.1/dist/axios.min.js"></script>

辅助作用的插件

SEO 优化,vite 实现预渲染vite-plugin-prerender

打包完成后,会根据配置的路由地址,在 dist 文件中生成对应的 index.html 文件

【在 dist 根目录下、dist/chat、dist/design 目录下都会生成 index.html 文件】

npm i vite-plugin-prerender -D

import vitePrerender from 'vite-plugin-prerender'
import path from 'path'

export default () => {
  return {
    plugins: [
      vitePrerender({
        // Required - The path to the vite-outputted app to prerender.
        staticDir: path.join(__dirname, 'dist'),
        // Required - Routes to render.
        routes: ['/', '/chat', '/design'],
      }),
    ],
  }
}

setup 语法糖 name 增强 vite-plugin-vue-setup-extend

setup 语法糖 name 增强,使 vue3 语法糖支持 name 属性

vue3 语法糖默认是没有 name 属性的,在我们使用 keep-alive 的时候需要用到 name


npm i vite-plugin-vue-setup-extend -D

import { defineConfig} from 'vite'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
export default  ({ mode }) => defineConfig({
  plugins: [
    vueSetupExtend()
  ]
}

使用

<script setup lang="ts" name="home"></script>

html 注入动态数据插件 vite-plugin-html

一个针对 index.html,提供压缩和基于 ejs 模板功能的 vite 插件

通过搭配 .env 文件,可以在开发或构建项目时,对 index.html 注入动态数据,例如替换网站标题 安装

npm i vite-plugin-html -D

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="./favicon.ico" />
    <link rel="stylesheet" href="./public/reset.css" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"
    />
    <title><%- title %></title>
  </head>
  <body>
    <div id="app"></div>
    <%- injectScript %>
  </body>
</html>

vite.config.ts

import { defineConfig, loadEnv } from "vite";
import { createHtmlPlugin } from "vite-plugin-html";
export default ({ mode }) =>
  defineConfig({
    // mode 环境变量名,若配置有.env.test,启动时 --mode test,这里的mode就是test
    plugins: [
      createHtmlPlugin({
        minify: true,
        /**
         * 在这里写entry后,你将不需要在`index.html`内添加 script 标签,原有标签需要删除
         * @default src/main.ts
         */
        entry: "/src/main.ts",
        /**
         * 需要注入 index.html ejs 模版的数据
         */
        inject: {
          data: {
            // 查找.env.test文件里面的VITE_PROJECT_TITLE,请以VITE_标识开头
            title: loadEnv(mode, process.cwd()).VITE_PROJECT_TITLE,
            injectScript: `<script src="/inject.js"></script>`,
          },
        },
      }),
    ],
  });

重启 vite 服务 vite-plugin-restart

通过监听文件修改,自动重启 vite 服务

最常用的场景就是监听 vite.config.js 和 .env.development 文件,修改 vite 配置文件和环境配置文件,是需要重启 vite 才会生效,通过这个插件,在修改上述两个文件则不需要重新运行

npm i vite-plugin-restart -D

配置:vite.config.js

import ViteRestart from "vite-plugin-restart";
export default {
  plugins: [
    ViteRestart({
      restart: ["vite.config.js"],
    }),
  ],
};

Vite 构建打包优化

设置路径别名

这样可以在引入文件时,不再需要使用相对路径,自定义起点路径,方便各个层级的代码引入。比如以下的代码示例,可以方便我们使用 src 目录下的文件。

// vite.config.ts
import { resolve } from 'path'

resolve: {
      // 结合tsconfig使用
      alias: {
        '@': resolve(__dirname, 'src'),
        components: resolve(__dirname, 'src/components'),
        assets: resolve(__dirname, 'src/assets'),
        views: resolve(__dirname, 'src/views')
      }
    },

// 结合ts使用
// tsconfig.json
{
  "compilerOptions": {
    ...
    "paths": {
      "@/*": ["./src/*"],
      "components/*": ["./src/components/*"],
      "assets/*": ["./src/assets/*"],
      "views/*": ["./src/views/*"]
    }
  },
}

less 引入全局公共样式

// vite.config.ts
export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        additionalData: `@import "@/styles/common.less";`,
      }
    },
  },
})

// src\styles\common.less
.ellipsis {
  overflow: hidden; /* 超出部分被隐藏 */
  text-overflow: ellipsis; /* 被裁剪的文本使用省略号表示 */
  white-space: nowrap; /* 禁止换行,文本在一行内显示 */
}
// 任意less文件
.text {
  .ellipsis;
}

配置打包文件分类输出

build: {
    rollupOptions: {
      output: {
        chunkFileNames: 'js/[name]-[hash].js', // 引入文件名的名称
        entryFileNames: 'js/[name]-[hash].js', // 包的入口文件名称
        assetFileNames: '[ext]/[name]-[hash].[ext]', // 资源文件像 字体,图片等
      }
    }
}

// 不建议配置

代码分割/产物拆包manualChunks

一般来说,如果不对产物进行代码分割(或者拆包),全部打包到一个 chunk 中,会产生如下的问题:

  • 首屏加载的代码体积过大,即使是当前页面不需要的代码也会进行加载。
  • 线上缓存复用率极低,改动一行代码即可导致整个 bundle 产物缓存失效。

而 Vite 中内置如下的代码拆包能力:

  • CSS 代码分割,即实现一个 chunk 对应一个 css 文件。
  • 默认有一套拆包策略,将应用的代码和第三方库的代码分别打包成两份产物,并对于动态 import 的模块单独打包成一个 chunk。

当然,我们也可以通过 manualChunks 参数进行自定义配置。

// vite.config.ts
{
  build {
    rollupOptions: {
      output: {
        // 1. 对象配置
        manualChunks: {
          // 将 React 相关库打包成单独的 chunk 中
          'react-vendor': ['react', 'react-dom'],
          // 将 Lodash 库的代码单独打包
          'lodash': ['lodash-es'],
          // 将组件库的代码打包
          'library': ['antd'],
        },
        // 2. 函数配置
          if (id.includes('antd') || id.includes('@arco-design/web-react')) {
            return 'library';
          }
          if (id.includes('lodash')) {
            return 'lodash';
          }
          if (id.includes('react')) {
            return 'react';
          }
      },
    }
  },
}

代码压缩+剔除 console+debugger

esbuild or terser, 默认启动的是 esbuild, esbuild 比 terser 快 20-40 倍,压缩率只差 1%-2%

esbuild:

只删除  console.log  和debugger

import { defineConfig } from "vite";
export default defineConfig({
  esbuild: {
    pure: ["console.log"], // 删除 console.log
    drop: ["debugger"], // 删除 debugger
  },
});
// 建议配置

删除所有的console语句和debugger,包括 console.log、console.warn、console.error 等

import {defineConfig} from "vite";
export default defineConfig({
    esbuild:{
        drop: ['console,'debugger'], // 删除 所有的console 和 debugger
    }
})

terser:

vite 4.X 版本已经不集成 terser,需要自行下载

npm i terser -D

只删除  console.log  和  debugger

import { defineConfig } from "vite";
export default defineConfig({
  build: {
    minify: "terser", // 启用 terser 压缩
    terserOptions: {
      compress: {
        pure_funcs: ["console.log"], // 只删除 console.log
        drop_debugger: true, // 删除 debugger
      },
    },
  },
});

删除所有的console语句和debugger,包括 console.log、console.warn、console.error 等

import { defineConfig } from "vite";
export default defineConfig({
  build: {
    minify: "terser", // 启用 terser 压缩
    terserOptions: {
      compress: {
        drop_console: true, // 删除所有 console
        drop_debugger: true, // 删除 debugger
      },
      format: {
        comments: false, // 删除所有注释
      },
    },
  },
});

其他打包配置优化

build: {
  chunkSizeWarningLimit: 2000,// chunk 超过 2000kb 之后进行提示
  cssCodeSplit: true, //css 拆分
  sourcemap: false, //不生成sourcemap
  assetsInlineLimit: 5000, //小于该值 图片将打包成Base64
},