结合vite,react,antd打包UI界面功能成一个js库,解决umd方式的 process is not defined 报错问题

vite+react+antd

业务场景

有这样一种业务场景,开发一个js类库,比如高德地图这种,引入高德地图js的sdk,可以基于sdk提供的接口二次开发一些业务功能,然而有些开发者为了方便,不想基于sdk二次开发UI功能,想使用默认提供的一些UI功能,这时我们就需要设计一种方案,引入sdk的js,可基于接口二次业务功能及UI,引入UI的js,快速便捷集成已有功能。

方案实现

sdk的js

这种js是纯js,没有UI框架,没有vite之前一般使用rollup进行打包,有了vite之后更方便了,vite相当于rollup的脚手架(我的理解),少了很多配置,默认都集成设置好了。

UI的js

bash 复制代码
yarn create vite my-vite-react-antd-lib --template react-ts

cd my-vite-react-antd-lib

yarn install

yarn run dev
  • 运行起来看看
  • 引入antd
bash 复制代码
yarn add antd
  • 修改App.ts文件引入使用antd的Button组件

修改配置文件,用于打包lib库模式

官网文档链接 cn.vitejs.dev/guide/build...

  • 修改vite.config.ts文件配置
ts 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, 'src/main_lib.tsx'),
      name: 'MyLib',
      // the proper extensions will be added
      fileName: 'my-lib',
    }
  }
})
  • 在src下新增main_lib.tsx文件
tsx 复制代码
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'

function renderHtml(htmlId: string) {
  ReactDOM.createRoot(document.getElementById(htmlId)!).render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
  )
}

export {renderHtml}

对比原本的main.tsx文件我们发现是将ReactDOM.createRoot这个封装了下,用函数包装了下,然后export导出

  • 运行yarn run build 后查看打包后的文件输出
  • 修改index.html中对生成的lib库的js进行使用
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- 这是原本的引入方式,es6模块的方式,引入src下的main.tsx,原本的build打包会生成项目级的包,那种可部署的前端项目 -->
    <!-- <script type="module" src="/src/main.tsx"></script> -->

    <!-- 这是引用lib库模式的方式,按之前的配置,lib会打包出es,umd两种js,这里先用es方式 -->
    <link rel="stylesheet" type="text/css" href="/dist/style.css">
    <script type="module">
      import {renderHtml} from '/dist/my-lib.js'
      renderHtml('root')
    </script>
  </body>
</html>

我们看到这个界面和之前的界面一模一样,说明我们的实验可能成功了

  • 接下来试试umd的方式
html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- 这是原本的引入方式,es6模块的方式,引入src下的main.tsx,原本的build打包会生成项目级的包,那种可部署的前端项目 -->
    <!-- <script type="module" src="/src/main.tsx"></script> -->

    <!-- 这是引用lib库模式的方式,按之前的配置,lib会打包出es,umd两种js,这里先用es方式 -->
    <!-- <link rel="stylesheet" type="text/css" href="/dist/style.css">
    <script type="module">
      import {renderHtml} from '/dist/my-lib.js'
      renderHtml('root')
    </script> -->

    <!-- 这是引用lib库模式的方式,按之前的配置,lib会打包出es,umd两种js,这里使用用umd方式 -->
    <link rel="stylesheet" type="text/css" href="/dist/style.css">
    <script src="/dist/my-lib.umd.cjs"></script>
    <script>
      MyLib.renderHtml('root')
    </script>
  </body>
</html>

发现有如下报错 process is not defined

这是因为process存在于Node环境中,不在浏览器环境里,默认打包会带入process,可以通过配置解决这个问题。看看官方说明

  • 修改配置
ts 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'

const nodeEnv = process.env.NODE_ENV === 'production' ? '"production"' : '"development"';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define: { 'process.env.NODE_ENV': nodeEnv },
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, 'src/main_lib.tsx'),
      name: 'MyLib',
      // the proper extensions will be added
      fileName: 'my-lib',
    }
  }
})

重新打包后发现包体积也变小了,js库文件中搜索不到process相关代码了

  • 查看页面显示正常
  • build的lib配置相关说明

现在可以通过antd进行快速的UI功能开发了,开发完成后打包出的是js,css,引入后调用函数运行就能渲染UI界面,这就是UI的js库模式

相关推荐
LucianaiB11 小时前
【元宝搜索开发者征文大赛】AI时代,学得慢就不用学?用元宝搜索打造一个教程保质期,确保每一个教程符合你的现状
前端·人工智能·ai编程
excel12 小时前
JavaScript 对象池:减少高频对象创建与 GC 压力
前端
陈随易13 小时前
纯 Go 写的 JS 引擎,跑分超过了 C 语言的 QuickJS
前端·后端·程序员
子兮曰15 小时前
Chrome 权限元素实战:144 与 151 的渐进增强写法
前端·javascript·chrome
IT_陈寒15 小时前
Redis连接池泄漏那次,我差点把生产环境搞崩了
前端·人工智能·后端
强尼银手15 小时前
我花一天做了个格斗游戏原型,判定全对,然后被「美术」劝退了
前端·javascript
石小石Orz15 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
陈随易16 小时前
专注飞机 FocusFlight,两个人把番茄钟做成了一趟航班
前端·后端·程序员
总要学点什么17 小时前
第98篇:三维特效-材质线效果——给一条线换十种材质,虚线的图案只填了一半
开发语言·前端·javascript·ecmascript·gis·webgl·材质
10share17 小时前
基于大模型的 i18n 方案:把中文原文当 Key,轻松搞定多语言维护
前端·vue.js