## Uni App Vite 项目基础配置

<p align="center">
  <img src="https://img.shields.io/npm/dw/@plugin-light/project-config-uni-vite">
  <img src="https://img.shields.io/npm/unpacked-size/@plugin-light/project-config-uni-vite">
  <img src="https://img.shields.io/npm/v/@plugin-light/project-config-uni-vite">
  <img src="https://img.shields.io/npm/l/@plugin-light/project-config-uni-vite">
  <img src="https://img.shields.io/github/last-commit/novlan1/plugin-light">
  <img src="https://img.shields.io/github/created-at/novlan1/plugin-light">
</p>

封装 `vite.config.ts` 的基本配置，开箱即用。

### 如何使用

安装

```bash
pnpm add @plugin-light/project-config-uni-vite -D
```

在 `vite.config.ts` 中添加如下设置：


```js
import { getUniVue3ViteConfig } from '@plugin-light/project-config-uni-vite';

import { defineConfig } from 'vite';

export default defineConfig(({ mode }) => {
  return getUniVue3ViteConfig({ mode });
});
```

### 参数

```ts
import type { Plugin, ServerOptions, CommonServerOptions, BuildOptions } from 'vite';
import type { Server } from 'node:https';
import tailwindcss from 'tailwindcss';
import type { UniTailwindPluginUserOptions } from '@uni-helper/vite-plugin-uni-tailwind';

import type { IRemoveVueDirectionOptions } from '@plugin-light/vite-plugin-remove-vue-directive';
import type { ICrossGameStyleOptions } from '@plugin-light/vite-plugin-cross-game-style';
import type { Options as TransformWebTagOptions } from '@plugin-light/postcss-plugin-transform-web-tag';
import type { Options as RemoveSelectorOptions  } from '@plugin-light/postcss-plugin-remove-selector';
import type { Options as LegacyOptions } from '@vitejs/plugin-legacy';
import type { Options as ESBuildOptions } from 'rollup-plugin-esbuild';

export interface IUniViteConfigOptions {
  mode: string;
  uni: any;

  // 端口，传递给 server.port
  port?: CommonServerOptions['port'];
  // https 配置，传递给 server.https
  https?: Server;
  // host 配置，传递给 server.host
  host?: CommonServerOptions['host'];

  // 前置插件
  prePlugins?: Array<Plugin>;
  // 后置插件
  postPlugins?: Array<Plugin>;

  // 对应 optimizeDeps.include
  optimizeDepsIncludes?: Array<string>;

  removeVueDirectionOptions?: IRemoveVueDirectionOptions;

  hmr?: ServerOptions['hmr'];

  // 语法警报列表，比如 v-model，destroyed
  warnList?: ICrossGameStyleOptions['warnList'];

  // transform-web-tag postcss 插件
  transformWebTagOptions?: boolean | TransformWebTagOptions;

  // remove selector postcss 插件
  removeSelectorOptions?: boolean | RemoveSelectorOptions;

  // uniTailwind 插件
  uniTailwindOptions?: boolean | UniTailwindPluginUserOptions;

  // tailwindcss postcss插件
  tailwindcssOptions?: boolean | Parameters<typeof tailwindcss>[0];

  // 构建选项
  buildOptions?: BuildOptions;

  // 是否使用chunk-split
  useChunkSplit?: boolean;

  // 是否使用 @vitejs/plugin-legacy
  // 传递对象格式将作为插件参数
  useLegacy?: boolean | LegacyOptions;


  // 传递给 uni 插件的参数
  uniOptions?: any;

  // 是否使用 rollup-plugin-esbuild
  // 传递对象格式将作为插件参数
  useESBuildPlugin?: boolean | ESBuildOptions;
}
```

### 注意事项

1. node.js 版本 >= 16

2. 支持在环境变量文件中配置 `VUE_APP_DIR`，环境变量文件可以是 `.env`, `.env.local` 等，举例如下：

```
UNI_INPUT_DIR = './src/project/guandan-match'
VUE_APP_DIR = project/guandan-match
```

### 对外脚本

本插件导出了几个脚本，外部可以使用。

1. 修复 `uni-app` 中 `monorepo` 仓库下打包路径问题

原理是修改了 `node_modules/@dcloudio/uni-cli-shared/dist/utils.js` 源码中的 `normalizeNodeModules` 方法，增加了下面这句：

```ts
str = str.replace(/^[./]*/, '');
```

使用方式：

```ts
require('@plugin-light/project-config-uni-vite/public-script/uni/fix-uni-dir');
```

2. 修复 `uni-app` 小程序下样式文件变化无法重新编译的问题


小程序开发时，独立的 `sass` 文件改动后并不会重新编译，用一个全新的示例工程也不可以。看了下源码，`uni-app` 是用 `import('vite').then({build}=>{})` 这种方式来启动的。

解决办法是利用 `gulp.watch`，监听 `./src/**/*.scss` 文件，然后修改下 `main.ts`，然后这样就能重新编译了。同时加上了 `debounce`。

使用方式：

```ts
require('@plugin-light/project-config-uni-vite/public-script/watch/watch-sass')();
```

### SCSS 警告说明

配置中屏蔽了 [import](https://sass-lang.com/documentation/breaking-changes/import/)、[legacy-js-api](https://sass-lang.com/documentation/breaking-changes/legacy-js-api/)、[mixed-decls](https://sass-lang.com/documentation/breaking-changes/mixed-decls/) 的相关警告信息。

原因如下：

1. `uni-app` 会把 `uni.scss` 放到业务每个 `scss` 前面，所以 `@import` 改成 `@use` 后，会报错 `@use rules must be written before any other rules`

2. `legacy-js-api` 问题，也是 `uni-app` 中使用了 `node-sass` 的 `renderSync`

3. `mixed-decls` 问题，涉及到样式优先级问题，业务自己判断即可

### useChunkSplit 说明

设置 `useChunkSplit` 为 `true` 后，将会开启：

1. 将 `aegis-v2`、`axios` 作为外链
2. 将一些库单独拆包
   - `t-comm、press-ui、press-plus、 pmd-npm` => `pmd-pkg`
   - `@dcloudio/uni-h5` => `uni-h5`

仅在 H5 下有效。

### 低版本浏览器兼容

使用方式为，设置 `useLegacy` 为 `true`。

原理，使用了 [@vitejs/plugin-legacy](https://www.npmjs.com/package/@vitejs/plugin-legacy) 这个三方库，以及[修复了它不支持 `CDN` 的问题](./vite-plugin-legacy-polyfill.html)。

是否会影响 H5 在高版本浏览器的性能？基本不会，具体可自行搜索 [@vitejs/plugin-legacy](https://www.npmjs.com/package/@vitejs/plugin-legacy) 的原理。

如何判断当前项目是运行的的 `module` 产物，还是 `legacy` 产物？控制台打印 `window.__vite_is_modern_browser`，为 `true` 则表示运行的是 `module` 产物，否则为 `legacy` 产物。

### 更新日志

[点此查看](./CHANGELOG.md)
