Home | Vite 官网中文文档

  • 社区插件:https://github.com/vitejs/awe...
  • 应用感触:Vite 本质是对各场景下的最佳计划的整合

react 罕用配置

import { defineConfig } from "vite";import path from "path";import reactRefresh from "@vitejs/plugin-react-refresh";import usePluginImport from "vite-plugin-importer";export default defineConfig({  resolve: {    alias: {      app: path.resolve(__dirname, "./src"),    },  },  plugins: [    reactRefresh(),    {      ...usePluginImport({        libraryName: "xxx/ui",        libraryDirectory: "es/components",        customName: (name) => {          return `@byte-design/ui/es/components/${name.replace(            name[0],            name[0].toLowerCase()          )}`;        },        // @ts-ignore usePluginImport 反对,然而类型束缚不正确        transformToDefaultImport: false,        camel2DashComponentName: false,        style: false,      }),      apply: "build",    },    {      ...usePluginImport({        libraryName: "xxx/icons",        libraryDirectory: "icons",        style: false,        camel2DashComponentName: false,      }),      apply: "build",    },    {      ...usePluginImport({        libraryName: "xxx/hooks",        libraryDirectory: "lib",        style: false,        camel2DashComponentName: false,      }),      apply: "build",    },  ],  build: {    lib: {      entry: path.resolve(__dirname, "src/index.ts"),      name: "brand_components",    },    // minify: false,    sourcemap: true,    rollupOptions: {      external: [        "axios",        "react",        "react-router-dom",        "react-dom",        /\xxx\/ui/,        /\xxx\/icons/,        /\xxx\/hooks/,      ],    },  },});

知识点

Es Module

  • import - JavaScript | MDN
  • 兼容 反对绝大多数古代游览器
动态引入
// html<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <script src="module1.js" type="module"></script>  </body></html>
// module1.jsimport { c1 } from './module2.js';console.log(c1())// module2.jsimport { count } from "./module3.js";export const c1 = () => {  return count;};

动静引入

export const c2 = () => {  import("./module4.js").then((res) => {    console.log(res.count2);  });};
  • 引申:React 组件动静引入
  • 意义:将一些应用场景较少的组件动静引入,缩小外围代码的体积
import React, { Suspense, lazy, useState } from 'react';const Head = lazy(() => {  return import('@byted/brand-components').then((res) => {    return {      default: res.Head,    };  });});const Loading = () => {    return <div>loading</div>;};const LoadHead = () => {  return (    <Suspense fallback={Loading}>      <Head        handleLangChange={() => console.log(11)}        ssoUrl="dasd"        projectType="aegir"      />    </Suspense>  );};export default LoadHead;

[React lazy/Suspense应用及源码解析
](https://zhuanlan.zhihu.com/p/...)

引申:Commonjs 的动静加载 - 打包的时候如何动静辨认文件

治理依赖 | webpack 中文网

对于,ES Module来说,这须要经验三个步骤:

  1. 结构 - 查找、下载并解析所有文件到模块记录中
  2. 实例化 - 在内存中寻找一块区域来存储所有导出的变量(但还没有填充值)。而后让 export 和 import 都指向这些内存块。这个过程叫做链接(linking)
  3. 求值 - 在内存块中填入变量的理论值。
    漫画:深入浅出 ES 模块

循环援用

  • CommonJS 模块输入的是一个值的拷贝,ES6 模块输入的是值的援用。
  • CommonJS 模块是运行时加载,ES6 模块是编译时输入接口。

esbuild

  • node_modules 模块的解决(将node_modules 申请门路带上 @modules 标识, 通过申请代理找到对应的三方模块)

依赖预构建

  • Vite 会将 package.json 中生产依赖 dependencies 进行预构建
  • 兼容 CommonJS 和 AMD 模块的依赖

    • 因为 Vite 的 DevServer 是基于浏览器的 Natvie ES Module 实现的,所以对于应用的依赖如果是 CommonJS 或 AMD 的模块,则须要进行模块类型的转化(ES Module)。
    1. 缩小模块间依赖援用导致过多的申请次数
  • 预构建产物
    https://juejin.cn/post/693040...

应用问题

因为esbuild 不能疏忽三方包的虚构依赖,导致开发构建谬误
  • 例如虚构滚动: react-virtualized
  • issue: https://github.com/bvaughn/re...
// node_modules/react-virtualized/dist/es/WindowScroller/utils/onScroll.js// 这个为虚构引入import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";
  • 解决方案:

通过 patch-package 对 react-virtualized 打一个本地补丁,将虚构援用给正文,在开发中才有此问题,在打包公布中没有此问题,所以通过补丁解决开发问题,根本无风险

按需引入

  • Vite 社区有多个 import 插件,多多少少都有一些问题 (没有残缺的反对babel-import-plugin 的配置)
  • 最终抉择: vite-plugin-importer (外部应用 babel-import-plugin)
  • vite-plugin-importer 问题
    Option 类型不欠缺,配置 transformToDefaultImport 报类型谬误
    customName 默认大写,须要自行处理
  • 我的项目配置如下:

    import usePluginImport from "vite-plugin-importer"; plugins: [  reactRefresh(),  {    ...usePluginImport({      libraryName: "xxxx/ui",      libraryDirectory: "es/components",      customName: (name) => {        return `xxx/ui/es/components/${name.replace(          name[0],          name[0].toLowerCase()        )}`;      },      // @ts-ignore usePluginImport 反对,然而类型束缚不正确      transformToDefaultImport: false,      camel2DashComponentName: false,      style: false,    }),    apply: "build",  },  {    ...usePluginImport({      libraryName: "xxx/icons",      libraryDirectory: "icons",      style: false,      camel2DashComponentName: false,    }),    apply: "build",  },],

内部依赖问题

  • 按需引入和内部依赖配置共存时候,间接配置按需生效的
  • 起因是:按需先执行会转换成门路,导致解决内部依赖时门路匹配不到
  • 解决办法:通过正则配置 external
external: [ "axios", "react", "react-router-dom", "react-dom", "@byted/hooks", /\xxx\/ui/, /\xxx\/icons/,],