umi 能适配 taro组件?

引言

本篇主要介绍了在umi项目中如何用taro组件去适配开发。

背景

随着技术不断更新,业务也迎来了新一代的发展。为了提高开发效率,我们采用Taro 来实行一套代码多端维护。因为我们商家端可以以楼层的方式去装修页面,装修端一直采用umi来维护,所以想要到达 Taro 代码也可以适配umi页面中,进行umi项目改造和适配。

介绍

Taro 是一个开放式跨端跨框架解决方案,可以通过类react\类vue等开发多端业务。Taro 最重要的能力当然是写一套代码输出多端皆可运行的代码。目前 Taro 已经支持一套代码同时生成 H5 和小程序,App端(React Native)、harmonyOS等程序。这意味着开发者可以聚焦于编写 React 代码,而无需为各个不同的终端去分别学习和编写对应的原生代码,大大提高了开发效率,降低了开发成本,尤其适合需要跨端部署应用的场景

umi是一个可插拔的企业级 React 应用框架,它内置了丰富的功能,例如路由系统、状态管理方案、按需加载等。开发者可以通过简单的配置快速搭建起一个结构清晰、性能优良的 React 项目,并且它有着良好的生态,众多插件能够进一步扩展项目的功能和开发体验,在开发 Web 端的 React 应用时往往是不少团队的首选。

理论上的适配可能性

从技术架构和遵循的语法规范角度来看,存在适配的基础。Taro 基于 React 语法,而 Umi 也是围绕 React 构建其应用体系。所以,Taro 组件本身如果是按照标准的 React 组件规范编写,理论上是可以被引入到 Umi 项目中的。比如,一个简单的 Taro 中定义的展示组件,像一个自定义的按钮组件,它有着标准的 React 组件结构,包含 props 接收属性、render 函数返回对应的 JSX 元素等,在 Umi 项目里按照正常的组件引入方式是有希望能够正常使用的。

然而,需要注意的是,Taro 在实现多端兼容的过程中,对一些原生 API 进行了自己的封装和处理,例如小程序端的页面生命周期函数、样式处理机制等方面和纯粹的 Web 端 React 应用(像 Umi 构建的常规项目)会有所不同。这些差异可能导致在实际适配过程中出现一些兼容性问题。

实施

Taro 运行包引入

Taro 本身是支持 web 端运行的,每端的运行、编译都是单独包。我们可以根据 H5 相关包进行整合。

路径 描述
@tarojs/webpack-runner H5 编译工具,主要用于设置、调用 Webpack
@tarojs/router H5 路由
@tarojs/taro-h5 H5 端根据微信小程序规范实现的 API
@tarojs/components H5 组件库(Web Components 版本)
@tarojs/components-react H5 组件库(React 版本)
babel-plugin-transform-taroapi Babel 插件,让 API 可以被 tree-shaking
postcss-plugin-constparse PostCSS 插件,用于处理 tabbar 的高度

上图表中我们看出taro-h5 是解决 API 的问题,components 是解决 Taro 组件的问题,那我们就可以将 这两个包 引入到 umi项目中。

将包进入umi中,我们有很多方式,比如 npm 直接植入、引入cdn等。考虑到 umi 在打包和编译时需要依赖很多内容,所有我们考虑直接引入 cdn 的方式。

我们在umi配置文件增加如下内容:

js 复制代码
  headScripts: [{
    src: 'https://xxx/taro-components.js',
    crossorigin: 'anonymous',
  }, {
    src: 'https://xxx/taro-h5.js',
    crossorigin: 'anonymous',
  }]

链接我们可以直接将 Taro 包中umd的类型植入到里面,之所以选择umd,是因为能够适应多种不同的运行环境。

如果是低版本的 Taro 找不到umd,可以在开源的 github上下载项目,将 webpack 配置中 target 换成 umd 方式重新打包。

如果组件库引入不了,需要加载 defineCustomElements 脚本自动注册使用的组件。

js 复制代码
import { applyPolyfills, defineCustomElements } from '@tarojs/components/loader'
applyPolyfills().then(() => defineCustomElements(window))

Taro 业务内容引入

前面我们提到了使用 Taro 在运行时将组件和api的包引入进来。如何才能将业务的内容展示出来,如果将组件内容直接引入umi项目中,在打包的时候会直接报错,而且还需要写编译的插件进行区分改造。这样对于我们完成效率大大降低了。

我们也是采用的将组件打包成 umd 的方式,再通过远程加载该 umd 再见。这样我们就可以通过运行时去渲染和运行组件。

我们利用 webpack 将 Taro 项目所用的组件进行打包成 umd 文件,配置如下:

js 复制代码
module.exports = {
  entry: '/src/component',
  output: {
    path: path.join(__dirname, "./dist"),
    library: ["platforms-comp", "[name]"],
    libraryTarget: "umd",
  },
  module: {
    ...
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    alias: {}
  },
  externals: {
    react: 'React',
    '@tarojs/components': 'components',
    '@tarojs/taro': 'Taro',
  },
  plugins: [
    ...
  ]
}

打包完成后发到远程连接

系统接入

umi 系统里面直接加载远程 umd 文件进行渲染

加载远程直接动态加载 script, 代码如下:

js 复制代码
const promise = new Promise((resolve, reject) => {
    const script: HTMLScriptElement = document.createElement('script')
    script.src = src 
    script.crossOrigin = 'anonymous'
    script.addEventListener('load', () => {
      resolve(null)
    })
    script.addEventListener('error', () => {
      reject()
    })
    document.body.appendChild(script)
  })
  this.scriptMap[src] = promise
  return promise

加载运行完后,umd 文件会把组件内容直接放入 window 下面,获取的数据直接取打包的 library 值。

js 复制代码
CompLoader.loadScript(this.props.url).then(() => {
  const target: any = window[compStr][this.props.name]
  this.setState({
    error: null,
    Component: target.default
  })
})

获取的内容直接渲染到标签就可以了。

总结

虽然 Umi 和 Taro 有着不同的定位和应用场景,但在一定条件下是可以尝试进行组件适配的。成功实现了部分功能的复用,减少了开发工作量,并且让项目能够更平滑地向多端进行部署。打破不同框架之间的壁垒,使得前端开发更加灵活高效,开发者能够根据项目需求更自由地组合不同框架的优势来构建高质量的应用。

相关推荐
余生H6 分钟前
前端Python应用指南(八)WebSocket与实时应用:用Flask和Django实现聊天系统
前端·python·websocket·实时通讯
国服第二切图仔10 分钟前
鸿蒙Next自定义相机开发时,如何解决相机在全屏预览的时候,画面会有变形和拉伸?
前端·javascript·harmonyos
it非鱼26 分钟前
超详细!uni-app Android本地打包傻瓜式教程
前端
坐镇指挥28 分钟前
vue组件设计
前端·javascript·vue.js
Mr。轩。32 分钟前
【Vue】分享一个快速入门的前端框架以及如何搭建
前端·vue.js·前端框架
yzzzz42 分钟前
JS 的蝴蝶效应 —— 事件流
前端·javascript·面试
三七林妹妹1 小时前
vulnhub DriftingBlues6靶机
前端·ecmascript·es6
杨荧1 小时前
【开源免费】基于Vue和SpringBoot的网上商城系统(附论文)
前端·javascript·jvm·vue.js·spring boot·spring cloud·开源
__night_1 小时前
kiran-qt5-integration
java·前端·qt
小李老笨了1 小时前
React组件化开发
前端·javascript·react.js