Bootstrap

[vue] Vite的使用2-vite.config.ts

vite.config.ts 配置

index.html需要在项目根路径下,否则启动打包存在问题

配置选项

root

是项目根目录,默认值是 process.cwd()-是项目的绝对路径,可以设置为"./"

base

开发或生产环境服务的公共基础路径,可以设置打包后资源的域名

  1. 当设置为 “”,打包 build 后的资源引入为
<link rel="modulepreload" crossorigin="" href="./assets/js/axios.js" />
  1. 当设置为 “https://xx.xx.xx”,打包 build 后的资源引入为
<link rel="modulepreload" crossorigin="" href="https://xx.xx.xx/assets/js/axios.js" />

需要设置为域名的情况:

当项目被作为微服务时相对加载的路径会存在问题,因此需要设置域名作为基础路径

在webpack时是可以根据运行时实现动态的域名加载资源,例如,根据被加载微服务的域名,动态设置了该微服务静态资源的域名

但是vite方式时,无法根据被加载微服务的域名,动态设置微服务中静态资源-css文件,js文件的不同域名!!!实际上base如果没有设置域名,使用的是相对值,则该微服务的静态资源使用的是基座的域名!!!是否能够设置为动态的域名

publicDir

静态资源路径,是不会做出任何处理的,直接复制路径中的内容到打包后的文件夹中

打包配置

assetsDir

默认"assets",静态资源的存放路径

outDir

默认"dist",打包后的输出路径

modulePreload

是否在 index.html 中注入 modulePreload 文件

插件使用

unplugin-vue-components

在使用@vue/cli脚手架时,Babel插件可用于按需引入ant-design-vue组件

在使用vite脚手架时,unplugin-vue-components插件可用于按需引入ant-design-vue组件

使用unplugin-vue-components插件后可自动生成components.d.ts文件,里面是所有被引用的ant-design-vue组件

当ant-design-vue为3.x时:

export default defineConfig(({ mode }) => {
  return {
    plugins: [
        Components({
          resolvers: [AntDesignVueResolver({ importStyle: "less" })]
        }) ]
  }
}

当ant-design-vue为4.x时,使用如上配置会报错

ERROR Failed to resolve import “ant-design-vue/es/config-provider/style/css” from “src\App.vue”. Does the file exist?

分析后发现ant-design-vue使用的是css-in-js,所以配置需要变更为:

export default defineConfig(({ mode }) => {
  return {
    plugins: [
        Components({
          // { importStyle: "less" }
          resolvers: [AntDesignVueResolver({
            resolveIcons: true,
            cjs: true,
            importStyle: false
          })]
        })
    ]
  }
}

样式丢失问题

修复上述问题后,开发环境组件正常展示的时候,发现打包出了问题,发现自定义的组件以及单文件中通过<style lang="css"></style>定义的样式都失效了,样式中的图片也自然失效了

通过观察发现打包生成的文件中存在定义的样式,但是确没有被引用,一直没有找到有效的解决方案,在ant-design-vue官网中提到说是插件’unplugin-vue-components’会引发一些不可预测问题,尝试删除unplugin-vue-components的使用,然后手动全局引入各组件的使用,发现样式问题消失!!!!

vite-plugin-html

类似于@vue/cli 将参数注入到 html 页面,vite可以通过 vite-plugin-html 插件注入参数,文件等

import qiankun from "vite-plugin-qiankun";
import { createHtmlPlugin } from "vite-plugin-html";
export default defineConfig(({ command, mode, ssrBuild }) => {
  const env="production"==mode
  return {
    plugins: [
      createHtmlPlugin({
        minify: true, //是否压缩 html
        //不需要在`index.html`内添加 script 标签,原有标签需要删除
        entry: "/src/main.ts", //入口文件
        // filename: "index.html",
        template: "/index.html", //模板相对路径
        // pages: [],//多页配置
        inject: {
          data: {            //数据注入
            title: "xxx",
            online: env
            injectScript: env ? `<script src="./env.js"></script>` : "",
            cdn: {
              css: [],
              js: [
                // '//cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js',
              ]
            }
          }
        }
      })
    ]
  };
});

如何在 html 添加额外的静态文件

  1. 在 index.html 中直接 添加文件引入

    <%- online ?'
    <script type="text/javascript" src="./env.js"></script>
    ' : '' %>
    

    online是通过vite.config.ts 中createHtmlPlugin配置的参数
    然后通过ejs的标签<%- %>引入该参数

  2. 通过 createHtmlPlugin 插件直接注入的方式

    • injectScript:通过injectScript配置需要注入的 js 文件
    • html 文件中需要添加注入的标签,一定要有注入标签否则无法成功
      <%- injectScript %>
    

不论配置的js文件是否存在,打包后的html文件中都有该js文件的引用!!!!

vite-plugin-qiankun

之前使用 qiankun 的时候都是配置@vue/cli 脚手架使用的,现在切换为 vite 脚手架,导出微服务等配置都发生了相应的变化

qiankun 环境判断

@vue/cli 使用 public-path.ts 作为设置微服务的注入,而 vite 环境中不需要该文件;

vite 中判断 qiankun 环境的值;

import { renderWithQiankun, qiankunWindow } from "vite-plugin-qiankun/dist/helper";
const isQiankun = qiankunWindow.__POWERED_BY_QIANKUN__;

微服务的导出

main.ts 中设置微服务的导出

const initQianKun = () => {
  renderWithQiankun({
    // 当前应用在主应用中的生命周期
    // 文档 https://qiankun.umijs.org/zh/guide/getting-started#
    bootstrap() {
      console.log("app bootstrap");
    },
    mount(props: any) {
      console.log("micro application mount");
      props.onGlobalStateChange((state, prev) => {
        console.log("micro onGlobalStateChange mount");
        // state: 变更后的状态; prev 变更前的状态
        // console.log(state, prev);
      });
      // props.setGlobalState(state);
      render(props);
    },
    //应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
    unmount(props: any) {
      console.log("micro application unmount");
      app.unmount();
      app = null;
      router = null;
    },
    //可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
    update(props: any) {
      console.log("micro application update props");
    }
  });
};

微服务的运行

main.ts 中微服务的运行

isQiankun ? initQianKun() : render();

开发模式使用微服务

import qiankun from "vite-plugin-qiankun";
export default defineConfig(({ command, mode, ssrBuild }) => {
  return {
    plugins: [
      qiankun(config.name, {
        // 微应用名字,与主应用注册的微应用名字保持一致
        useDevMode: true //开发模式导出微服务
      })
    ]
  };
});

vite-plugin-dynamic-base

网上说是用于微服务时设置动态域名,本人尝试后发现存在问题,并不能成功

export default defineConfig(({ command, mode, ssrBuild }) => {
  return {
    base:"/__dynamic_base__/",
    plugins: [
      dynamicBase({
        publicPath: `window.__dynamic_base__`,
        transformIndexHtml: false
      }),
    ]
  }
}

const prefix=“/dynamic_base/”;

const publicPath= window.__dynamic_base__;

basepublicPathtransformIndexHtmlDNS
prefixpublicPathfalsemicroDns/dynamic_base
./publicPathfalsemainDns/assets/js/assets
prefixpublicPathtruemainDns/dynamic_base
./publicPathtruemainDns/assets/js/assets

根据官网配置未找到有效内容,__dynamic_base__未被替换,此插件不可用

实战应用

Cannot find module ‘@/config/i18n’ or its corresponding type declarations

自己编写的 ts 文件的引入均报以上类似错误,分析觉得是 ts 的检查问题,因此在 tsconfig.json 文件中添加如下配置

{
  "compilerOptions": {
    "baseUrl": ".",
    "types": ["vite/client", "jest"],
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
;