vite构建项目并支持微前端

目录
  • 基础配置
  • 支持微前端构建
  • 其他说明
    • 1. 老旧浏览器的支持
    • 2. 关于 TypeScript 的说明
    • 3. 对接 CDN
    • 4. 构建出错
      • 4.1 找不到包
      • 4.2 请求超时
      • 4.3 导入模块出错
  • 小结

得益于 esbuild 的超高性能,vite 在诞生之初就备受关注,且一直保持着活跃的开发迭代。截至目前,vite 已经迭代到了 2.7.10 版本,各方面也基本具备了在生产使用的条件。这段时间,我在项目中尝试了使用 vite 进行打包构建,本文就是这次构建的过程记录。

基础配置

首先使用vite 官方脚手架生成项目。

yarn create vite vite-demo --template react-ts

上面这行命令使用 react-ts 模板创建了一个叫 vite-demo 的项目。由于我在的团队日常使用 react 和 typescript 开发居多,因此选择了 react-ts 这个模板,vite 官方支持的模板还有很多,可以在 create-vite 中查看。

项目初始化完成以后,目录结构如下:

.
|____index.html
|____.gitignore
|____package.json
|____tsconfig.json
|____vite.config.ts
|____src
| |____App.tsx
| |____main.tsx
| |____App.css
| |____index.css
| |____vite-env.d.ts
| |____logo.svg
| |____favicon.svg

其中 vite.config.ts 内容如下:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()]
})

可以看出,vite 官方已经做了比较完善的封装,相较于之前版本,开发体验提升了很多。

按照指示安装完依赖,启动应用以后,速度确实很快。现在我们来做一些基本改造。

我通常使用 less 来写样式,vite 已经做了很好的支持,在安装完依赖以后,只需要直接在代码中引用 xxx.less 即可。对于一个久经考验的开发者来说,样式还是要引入作用域的,通常使用 css modules。

安装 less 预处理器,

yarn add --dev less

然后修改 vite.config.ts 文件,添加 css modules 配置:

export default defineConfig({
  ...
  css: {
    modules: {
      localsConvention: 'camelCaseOnly', // 我们使用驼峰形式
    },
  },
  ...
})

添加完配置以后,只要将原来的 xxx.less 改成 xxx.module.less 即可,这点与 create-react-app 是一样的。

这里推荐一个 vscode 插件 clinyong.vscode-css-modules 可以实现编码时样式类名的智能提示,同时点击样式类名可以跳转到样式定义的地方,非常好用。如果在编写样式时使用的是中划线形式的命名方式,比如 .xxx-container,那么需要额外配置这个 vscode 插件,如下

{
  "cssModules.camelCase": true
}

这样可以实现编写样式时使用中划线形式,在代码中使用的还是驼峰式的。

由于我开发的是一个中后台项目,使用了 antd 和 lodash,大家都知道,这两个是按需加载大户,以前我们使用 babel-plugin-import 来处理,vite 生态里也有很多类似的方案。我选用了 vite-plugin-imp 这个插件,修改 vite.config.ts 如下:

import vitePluginImp from 'vite-plugin-imp';

export default defineConfig({
  ...
  plugins: [
    ...
    vitePluginImp({
      libList: [
        {
          libName: 'lodash',
          libDirectory: '',
          camel2DashComponentName: false,
        },
        {
          libName: 'antd',
          style(name) {
              // use less
              return `antd/es/${name}/style/index.js`;
          },
        },
      ],
    }),
  ],
  css: {
    ...
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
});

antd 已经默认支持了 Tree Shaking,上面的配置最终只会处理样式的按需加载。lodash 不支持 Tree Shaking,我们也可以使用 ESM 版本 lodash-es,这样就可以不使用 vite-plugin-imp 了,配置如下:

export default defineConfig({
  resolve: {
    alias: [{
      find: /^lodash$/,
      replacement: 'lodash-es',
    }],
  },
});

通常,我们在开发前端项目时,需要一些代理来调用后端 API 接口,vite 配置如下:

export default defineConfig({
    ...
    server: {
      proxy: {
        '/api_path/': {
          target: 'http://xxx.server.domain.com/',
          changeOrigin: true,
        },
      },
    },
});

代理底层都是基于 http-proxy 实现,这里不做过多说明了。

现在可以愉快的开发代码了。

支持微前端构建

因为我们的中后台应用是使用微前端(qiankun)来管理的,上面的配置,打包完成后不能被 qiankun 识别,主要原因可以看看这里,我们需要做一些额外处理。

我们知道,使用 webpack 构建微前端是,需要添加如下三个配置项:

{
  output: {
    libraryTarget: 'umd',
    library: `${APP_NAME}-[name]`,
    jsonpFunction: `webpackJsonp_${APP_NAME}`,
  }
}

在 vite 中,可以直接通过设置 build.rollupOptions.format 为 umd 来设置 UMD 规范,但是实际构建结果却不能被 qiankun 识别,猜想是可能跟 vite 使用 html entry 有关系。

换一个思路,我们把当前整个应用当做一个 library 来构建,输出为 UMD 规范,然后手动写入一个 html 文件,加载这个输出的 JS。

修改配置如下:

export default defineConfig({
  ...
  build: {
    lib: {
      name,
      entry: path.resolve(__dirname, 'src/index.tsx'),
      formats: ['umd'],
    },
  },
  ...
})

配置完成之后,执行 yarn build 提示如下错误:

UMD and IIFE output formats are not supported for code-splitting builds.

因为我们的应用中有路由,使用了按需加载。我们将 rollup 的 inlineDynamicImports 配置打开:

export default defineConfig({
  ...
  build: {
    rollupOptions: {
      output: {
        inlineDynamicImports: true,
      },
    },
  },
  ...
})

这样,构建完成之后,dist 目录下有两个文件 style.css 和 xxx.umd.js

现在我们要生成 index.html 了。

因为 vite 在开发态直接使用 ES Modules,是不打包的,因此生成开发态的 index.html 和生产的 index.html 是不同的。

我们修改项目根目录下的 index.html 为:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" rel="external nofollow"  />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
    <!-- style placeholder -->
  </head>
  <body>
    <div id="root"></div>
    <!-- script placeholder -->
  </body>
</html>

注意当中的两行注释,我们会在开发态和生产构建做不同的处理。

vite 插件 API 中有一个 transformindexhtml 可以定制开发态的 html 内容,因此,我们开发态的配置如下:

// https://vitejs.dev/config/
export default defineConfig({
  ...
  plugins: [
    ...
    {
      name: 'dev html',
      apply: 'serve',
      transformIndexHtml(indexHtml: string) {
        return indexHtml
          .replace('<!-- style placeholder -->', '')
          .replace('<!-- script placeholder -->', '<script type="module" src="/src/index.tsx"></script>');
      },
    },
    ...
  ],
});

生产构建需要借助于 @rollup/plugin-html 这个插件来实现定制 html 内容。

import html from '@rollup/plugin-html';
import fs from 'fs';

const entryHtml = fs.readFileSync('./index.html', { encoding: 'utf-8' });

export default defineConfig({
  ...
  plugins: [
    ...
    {
      name: 'build html',
      apply: 'build',
      ...html({
        template: () => {
          return entryHtml
            .replace(
              '<!-- style placeholder -->',
              '<link rel="stylesheet" type="text/css" href="style.css" rel="external nofollow"  />',
            )
            .replace(
              '<!-- script placeholder -->',
              `<script type="text/javascript" src="${name}.umd.js"></script>`,
            );
        },
      }),
    },
    ...
  ],
});

通过上面的配置,再次构建,qiankun 可以加载这个子应用了。

其他说明

1. 老旧浏览器的支持

由于我这次的项目是中后台项目,对老旧浏览器的支持诉求不强烈,就没有在项目中做处理。其实 vite 官方也是给了解决方案的,就是 @vitejs/plugin-legacy 这个插件。

原理也非常简单,就是通过 <script nomodule> 来实现在不支持 ES Modules 的浏览器执行相关脚本,同时使用 SystemJS 来加载模块。

2. 关于 TypeScript 的说明

脚手架初始化完成以后就可以用 TypeScript 开发,这里格外说明一点,就是需要开启编译器选项 isolatedModules:true,因为 vite 使用 esbuild 处理 ts 文件,只将 ts转换成 js 而不做类型检查(依赖编辑器处理类型检查,比如 vscode)。因此,当遇到一些纯类型的导入导出时,会出错,需要开启 isolatedModules:true 来避免这个问题。如果因为一些原因无法开启这个选项,则可以使用 rollup-plugin-friendly-type-imports 这个包来处理,这个包的 README 里也说明了为什么会有这样的问题。

3. 对接 CDN

基于上面的配置构建出来的结果,浏览器在加载资源的时候,都是使用的根路径(/)加载,如果使用 CDN 的话会出现资源加载 404 的问题。

我们可以配置 base 来设置基础路径,类似于 webpack 的 PUBLIC_PATH

export default defineConfig({
  base: '/some/public/path',
})

4. 构建出错

4.1 找不到包

报错信息为:

[plugin: vite:dep-scan] Failed to resolve entry for package "xxx"

通常是依赖包未在 package.json 正确配置 main、module 等字段,导致 vite 无法找到包的入口。

可以设置通过设置别名的方式,将其映射到正确的文件上。

export default defineConfig({
  resolve: {
    alias: [{
      find: /^SOME_PACKAGE_NAME$/,
      replacement: 'SOME_PACKAGE_NAME/dist/xxx.es.js',
    }],
  },
});

4.2 请求超时

报错信息为:

net::ERR_ABORTED 408 (Request Timeout)

启动开发服务器后,浏览器出现请求超时错误。是因为 vite 检测到对依赖包的请求,且该依赖尚未被 vite 处理过,这时候会会触发预构建,导致请求超时以及页面重载。

我们可以多刷新几次等 vite 完成预构建,也可以将依赖加入 optimizeDeps.include 来提前处理。

4.3 导入模块出错

报错信息为:

Internal server error: Failed to resolve import "./chunk-7L3SPMWF.js" from "node_modules/.vite/antd.js?v=7bec0e27". Does the file exist?

可能是因为一些依赖包输出的格式 vite 还不支持,可以看看这个 issue

这个错误只在开发服务器运行处理过程中存在,待页面正常展示后就不出现了,忽略这个错误之后,目前看也没产生什么影响。

小结

总体来说,vite 已经基本具备了生产使用的条件。如果是常规的应用开发,vite 的配置非常简单,可以说是开箱即用。如果需要添加额外的配置也非常方便。

目前比较大的问题是周边生态还不是特别成熟,很多已经成熟的包对于 vite(ES Modules)的支持比较弱。同时,如果团队内基建氛围比较浓厚的话,自己开发的工具包也要考虑这方面的问题。

到此这篇关于vite构建项目并支持微前端的文章就介绍到这了,更多相关vite构建项目内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 如何为老vue项目添加vite支持详解

    1.前言 接手公司的某个项目已经两年了,现在每次启动项目都接近1分钟,hmr也要好几秒的时间,but vite2发布之后就看到了曙光,但是一直没有动手进行升级,昨天终于忍不住了,升级之后几秒钟就完成了. vite -- 一个由 vue 作者尤雨溪开发的 web 开发工具,它具有以下特点: 快速的冷启动 即时的模块热更新 真正的按需编译 2.开始升级 注:只是升级了开发环境,打包依旧是webpack(也试过打包也用vite,但是打包后发现iview的字体图标出现问题了,初步验证是静态资源的问题,v

  • 基于Vite2.x的Vue 3.x项目的搭建实现

    创建 Vue 3.x 项目 npm init @vitejs/app my-vue-app --template 引入 Router 4.x npm install vue-router@4 --save 配置路由 在更目录中添加一个 router 的文件夹,新建 index.js Router 4.x 为我们提供了 createRouter 代替了 Router 3.x 中的 new VueRouter,用于创建路由. // Router 4.x import { createRouter,

  • vite2.0+vue3移动端项目实战详解

    一.涉及技术点 vite版本 vue3 ts 集成路由 集成vuex 集成axios 配置Vant3 移动端适配 请求代理 二.步骤 vite+ts+vue3只需要一行命令 npm init @vitejs/app my-vue-app --template vue-ts 配置路由 npm install vue-router@4 --save 在src下新建router目录,新建index.ts文件 import { createRouter, createWebHashHistory, Ro

  • vite+vue3+element-plus项目搭建的方法步骤

    使用vite搭建vue3项目 通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目. $ npm init vite-app <project-name> $ cd <project-name> $ npm install $ npm run dev 引入Element Plus 安装Element Plus: npm install element-plus --save main.js中完整引入 Element Plus: import { createApp

  • 图文详解如何在vue3+vite项目中使用svg

    今天在vue3+vite项目练习中,在使用svg时,发现之前的写法不能用,之前的使用方法参考vue2中优雅的使用svg const req = require.context('./icons/svg', false, /\.svg$/) const requireAll = requireContent => requireContent.keys().map(requireContent) requireAll(req) 然后就各种资料查找,终于实现了,废话不多说,直接上代码: stept1

  • 详解antd+react项目迁移vite的解决方案

    antd+react+webpack往往是以react技术栈为主的前端项目的标准组合,三者都有成熟的生态和稳定的表现,但随着前端圈的技术不断革新,号称下一代构建平台vite2的发布,webpack似乎不那么香了,为什么这么说呢,因为vite太快了.经过一段时间的尝试,决定在项目中把webpack替换成vite试试,遂写成本文分享给大家. Vite是什么 作为本文的主角,首先简单介绍一下vite这个构建工具,该工具是尤雨溪推出的[下一代前端开发和构建工具],vite其实也不是一个新的工具,早在一年

  • Vite搭建React项目的方法步骤

    前言 日常放鸽,火钳刘明 这是一个基于 vite 搭建的 React 的项目,开发体验非常棒. 创建一个 Vite 项目 yarn create @vitejs/app 如上图,选择了 react-ts 预设模板,如果出现下图一样的工程 yarn // 安装依赖 yarn dev // 启动开发环境 打开浏览器输入http://localhost:3000/#/,如上图所示的话.那么恭喜你,你可以正常开发 React 项目了.完结撒花 如果不行的话,直接看 vite 官网,它比我写的详细 改造工

  • Vite创建项目的实现步骤

    目录 前言 yarn create 做了什么 源码解析 项目依赖 模版配置 工具函数 copy copyDir emptyDir 核心函数 命令行交互并创建文件夹 写入文件 小结 前言 随着 Vite2 的发布并日趋稳定,现在越来越多的项目开始尝试使用它.我们使用 Vite 是一般会用下面这些命令去创建一个项目: // 使用 npm npm init @vitejs/app // 使用 yarn yarn create @vitejs/app // 想指定项目名称和使用某个特定框架的模版时,可以

  • vite构建项目并支持微前端

    目录 基础配置 支持微前端构建 其他说明 1. 老旧浏览器的支持 2. 关于 TypeScript 的说明 3. 对接 CDN 4. 构建出错 4.1 找不到包 4.2 请求超时 4.3 导入模块出错 小结 得益于 esbuild 的超高性能,vite 在诞生之初就备受关注,且一直保持着活跃的开发迭代.截至目前,vite 已经迭代到了 2.7.10 版本,各方面也基本具备了在生产使用的条件.这段时间,我在项目中尝试了使用 vite 进行打包构建,本文就是这次构建的过程记录. 基础配置 首先使用v

  • 如何用Vite构建工具快速创建Vue项目

    目录 和Webpack相比,Vite具有以下特点 Vite构建Vue项目 构建过程可能会发生的一些问题 总结 和Webpack相比,Vite具有以下特点 1.快速的冷启动,不需要等待打包 2.即时的热模块更新,真正的按需编译,不用等待整个项目编译完成 Vite构建Vue项目 前提:安装Node.js和Vite 第一步通过npm创建Vite项目 npm init vite-app 项目名称 # 例如 npm init vite-app HelloVue 第二步当项目创建成功后,cd到项目目录 cd

  • vite构建vue3项目的全过程记录

    目录 环境准备 创建项目 启动 总结 环境准备 安装最新版本 @vuejs/app yarn global add @vue/cli # OR npm install -g @vue/cli 升级到最新版本 @vitejs/app yarn global upgrade @vue/cli # OR npm update -g @vue/cli 查看 vue 版本 vue -V 兼容性注意 Vite 需要 Node.js 版本 >= 12.0.0. 故切换 node 版本,可查看该文章:使用 nv

  • 微前端qiankun改造日渐庞大的项目教程

    项目背景 很多小伙伴在工作中都碰到过和我一样的场景,手上的某个项目越来越大,眼看着每次build时间越来越长,吐了.在杭州某独角兽我碰到了这样的一个项目,他叫运营后台,听名字就知道,他的主要用户是运营人员.问题就是随着公司业务的越来越多,这个运营后台承担的已经不是某一块业务了,而是所有业务的运营操作的中后台都在这上面.你可以这样理解,这个系统的每个一级菜单都是一块独立的业务,相互之间没有任何瓜葛:按常规的理解,这应该是单独的每一个project比较合理,但是正因为他的用户又都是公司的同一群人,他

  • 使用Vite+Vue3+Vant全家桶快速构建项目步骤详解

    目录 引言 一.vue3全家桶模板介绍 1.版本依赖 2.全家桶内置集成 二.安装 tive-cli 命令行工具 三.生成项目 四.项目体验 引言 随着Vue3 和 Vite 版本的不断更新完善,开发体验有了质的飞跃.因此,越来越多的大厂也逐步拥抱 Vue3. 利用Vite 脚手架工具可以很轻松生成以 Vue3 为模板的项目,但是作为Vue全家桶的 vue-router.vuex.axios等成员,需要自己一个一个去配置.于是便自行开发了本文讲到的 tive-cli 脚手架模板工具,只需短短几个

  • 基于Vue CSR的微前端实现方案实践

    在这里就不讲微前端的各种优缺点,直接假设你在负责一个中后台管理系统的开发,所有的业务模块全部都在一个项目中打包,随着业务量的不断增长,编译越来越慢,你期望可以从老的项目中将新的业务进行独立开发.独立部署,以微应用的形式嵌入到老项目中. 本篇文章的受众是那些希望在新老的项目中,在不需要你对老项目进行改动老项目的前提下,嵌入微应用,如果本篇文章对你有帮助,请点个:+1:! 核心要素 构建生产环境代码,输出远程组件所需的 JSON 通过 ajax 请求,拿到这个 JSON 的数据,传给 远程组件 新项

  • JS微前端MicroApp基础使用

    目录 1. 介绍 2. 主应用 2.1 路由配置和基础页面 2.2 全局生命周期配置 2.3 主应用插件系统 3. 子应用 3.1 Webpack + Vue 子应用 3.2 Webpack + React 子应用 4. 应用路由配置说明 4.1 主应用路由 4.2 子应用路由 1. 介绍 MicroApp 是“京东零售”团队在2021年7月正式发布的一个微前端框架,并且抛弃了 Single SPA 的实现理念,基于 CustomElement 和 ShadowDom 来实现. MicroAPP

  • 微前端架构ModuleFederationPlugin源码解析

    目录 序言 背景 MF 基本介绍 应用场景 微前端架构 服务化的 library 和 components ModuleFederationPlugin 源码解析 入口源码 Exposes Remotes Shared 小结 总结 序言 本文是 Webpack ModuleFederationPlugin(后面简称 MF) 源码解析 文章中的第一篇,在此系列文章中,我将带领大家抽丝剥茧.一步步地去解析 MF 源码.当然为了帮助大家理解,可能中间也会涉及到 Webpack 源码中的其它实现,我会根

  • 基于Vue实现微前端的示例代码

       前端微服务化一直是前端社区的一个热门话题,早在2018年就有不少开发者提出过各种解决方案.或许是未得精髓,个人认为基于Web Components的实现脱离整体打包逻辑的,难以工程化.直到遇到了vue-cli 3,子模块打包的问题得以迎刃而解.2019年秋,团队内部初步实现前端分布式开发,解决了集中式开发部署的"老大难"问题.个人认为,随着WebAssembly等技术的兴起,"前端后移"越来越明显,前端微服务会成为大前端的一个趋势.下面简单分享下本人对前端微服

随机推荐