java转换rn,taro-build 之 RN 转换

taro-build

taro-build:命令行工具,将 react 代码转换成 weapp/swan/alipay/tt/h5/quickapp/rn 几种类型的应用。

其参数包括如下:

type,待转换的类型,包括 weapp/swan/alipay/tt/h5/quickapp/rn。

watch,监听模式,可监测文件改动,自动做转换。

page,编译页面。

component,编译组件。

ui,编译 taro ui 库。

ui-index,指定 taro ui 库的索引文件路径。

plugin,编译 taro 插件,微信小程序所用。

port,指定端口。

release,发布快应用 quickapp。

在这里我们需要梳理转换为 rn 的流程,因此 type 传入 rn即可。

launch.json 的配置如下:

{

// Use IntelliSense to learn about possible attributes.

// Hover to view descriptions of existing attributes.

// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387

"version": "0.2.0",

"configurations": [

{

"type": "node",

"request": "launch",

"name": "Launch Program",

"skipFiles": [

"/**"

],

"program": "${workspaceFolder}/bin/taro-build",

"preLaunchTask": "tsc: build - tsconfig.json",

"outFiles": [

"${workspaceFolder}/dist/**/*.js"

],

"cwd": "${workspaceFolder}/myApp",

"args": [

"--type","rn"

]

}

]

}

cwd 为待转换 taro 项目路径。

转换过程

主要代码逻辑在 src/rn.ts -> build() 中,转换输出目录为 rn_tmp。步骤如下:

检查依赖

检查 package.json 中是否有 rn 相关依赖,即检查 dependencies 中是否包含 react-native。若没有,更新 package.json 文件添加如下依赖,并进行安装。

{

"@tarojs/components-rn": "^${version}",

"@tarojs/taro-rn": "^${version}",

"@tarojs/taro-router-rn": "^${version}",

"@tarojs/taro-redux-rn": "^${version}",

"react": "16.3.1",

"react-native": "0.55.4",

"redux": "^4.0.0",

"tslib": "^1.8.0"

}

代码与样式转换

主要工作由 Compiler.buildTemp() 来实现。

其遍历 taro 工程下的所有文件,调用 processFile 进行处理,处理流程如下:

如果为样式文件,不做处理。

如果为 js 文件,则会进行 ast的处理和依赖样式的转换。

其余类型文件,比如 html,则直接 copy 到 rn_temp 文件夹。

如果是 watch 模式,则会在本地启动一个 rn 打包服务器。

打包为 bundle,调用 react-native 的 cli.js 实现。

下面着重讲第二步,分为「代码转换」和「样式转换」。

代码转换

其主要调用 transformJSCode,返回生成的代码和引用的样式文件路径集合,处理如下:

调用 wxTransformer 转换成 ast,其会将 ts 代码编译成 js 代码后,在 babel 中设置一系列的插件返回ast。

遍历 ast,进行如下处理:

处理 ClassDeclaration/ClassExpression

即处理类的声明,获取当前类名。分为以下两种情况:

类继承自 Taro.xx,即 Taro 的预置组件。注意这里 Taro 的值是从下面的 ImportDeclaration 中获得的。即 import Taro from '@tarojs/taro。

类继承自 Component/PureComponent。

如果当前类无类名,即为 export default class extends xxx 的情况,则默认加上类名 _TaroComponentClass,并修改 ast。最终记录类名。

处理 ExpressionStatement

预处理 require 样式文件,将其改成 import 的方式。

处理 ImportDeclaration

处理 import 的样式文件,保存其路径

处理 js/ts 文件,重新设置其相对路径

如果从 @tarojs/taro 中导入,改成 @tarojs/taro-rn

import Taro, { getEnv, Component } from '@tarojs/taro

注意这里有两种类型,可以结合 ast 自行查看。

ImportDefaultSpecifier:默认导出类型,非 {} 包裹,这里为 Taro。

ImportSpecifier:{} 包裹,这里为 Component 和 getEnv。

这里会记录下 ImportDefaultSpecifier中 Taro 的值,在后面处理中会用到,因为需要 import。

同时会检查导入的变量是否属于 taroApis 。上述例子中,getEnv 就是 taroApi,则需要导入。

变量需要被使用才会被 import,转换后如下:

import { Component } from "@tarojs/taro-rn";

import { getEnv } from "@tarojs/taro-rn";

可能有人会疑惑为啥 import Taro from '@tarojs/taro-rn'; 没有生成。其实这句的导入是在后面过程才处理。

如果从 @tarojs/redux 中导入,改成 react-redux-rn

如果从 @tarojs/mobx 中导入,改成 @tarojs/mobx-rn

如果从 @tarojs/components 中导入,改成 @tarojs/components-rn

处理 ClassProperty

主要处理入口文件的 config 属性:

处理 pages,记录路径,然后移除节点

处理 tabBar,记录 icon 路径,然后移除节点

将 config 设置为 static,由于再次生成 ast 时使用了 babel-plugin-transform-class-properties 插件,所以最终表现为:

App.config = { window: { xx: 'yy'}

最终只剩下 windows 相关的属性。

处理 ClassMethod

注意这里仅处理入口文件 app.js。

标记是否有constructor/componentDidMount/componentDidShow/componentDidHide/componentWillUnmount

遍历 render方法的语法树,生成 JSXElement 的代码。

比如 App.js 中 render 方法如下:

render () {

return (

)

}

那么代码为 。

处理 ExportDefaultDeclaration

如果为入口文件,标记有 export default。

处理 JSXElement

标记有 JSX。

处理 JSXOpeningElement

处理 相关,获取 store 名称。

处理 Program 的 exit。

ClassMethod

主要处理入口文件。

在 constructor 中插入语句 Taro._$app = this

在 componentDidMount 中插入语句 this.componentDidShow(),前提为 componentDidShow 存在。

在 componentWillUnmount 中插入语句 this.componentDidHide(),前提为 componentDidHide 存在。

在render 中插入,根据是否有 pages,provider 等生成最终的结构。

比如有 pages 生成如下:

render() {

return

;

}

ClassBody

处理一些异常情况。

若有componentDidShow,但没有 componentDidMount 方法,则插入 componentDidMount 方法,并添加语句 this.componentDidShow && this.componentDidShow()。

若有componentDidHide,但没有 componentWillUnmount 方法,则插入 componentWillUnmount 方法,并添加语句 this.componentDidHide && this.componentDidHide()。

若没有constructor 方法,则添加如下代码

constructor() {

super(...arguments);

Taro._$app = this;

}

CallExpression

如果有直接调用 Taro.render(),则进行移除。

如果有 JSX,则导入 import React from 'react'

如果有使用 Taro,则导入 import Taro from @tarojs/taro-rn'

入口文件处理

导入依赖的页面文件路径。

导入 tarbBarIcon 路径,如果有设置 tarBar 的话。

末尾插入一些额外的代码,比如页面路由/ 初始化 api 能力/ px 转换等。

// router 相关

const RootStack = TaroRouter.initRouter([['pages/index/index', pagesIndexIndex]], Taro, App.config);

// api 能力

Taro.initNativeApi(Taro);

// pxTransform

Taro.initPxTransform({

"designWidth": 750,

"deviceRatio": {

"640": 1.17,

"750": 1,

"828": 0.905

}

});

// 默认导出

export default App;

注意点

上述操作对 ast 修改完成后,会调用 babel.transformFromAst,设置一系列插件重新生成 ast,再转换为最终代码。

// 将 jsx 中样式的写法转换为 stylesheet

babel-plugin-transform-jsx-to-stylesheet

// 使用 class property

babel-plugin-transform-class-properties

// 使用装饰器

babel-plugin-transform-decorators-legacy

// 移除无用 import

babel-plugin-danger-remove-unused-import

// 定义常量信息,这里用来设置环境,process.env.TARO_ENV

babel-plugin-transform-define

转换完成后,会发现如下代码:

let App = class App extends Component {}

声明的 class 被赋值给了变量 App。这其实是通过步骤 1 中的插件 babel-plugin-transform-decorators-legacy 完成的。

转换样式

调用 compileDepStyles,主要处理逻辑在 StyleProcess 中。

读取样式文件,进行 scss/sass/less 的预处理后,返回 css string。

使用 postcss 插件 pxtransform 进行单位转换,具体计算操作在 createPxReplace。

调用 taro-css-to-react-native 进行样式的处理。

app.scss:

.node {

background-color: red;

}

转换之后生成app_styles.js:

import { StyleSheet, Dimensions } from 'react-native'

// 一般app 只有竖屏模式,所以可以只获取一次 width

const deviceWidthDp = Dimensions.get('window').width

const uiWidthPx = 375

function scalePx2dp (uiElementPx) {

return uiElementPx * deviceWidthDp / uiWidthPx

}

export default StyleSheet.create({

"node": {

"backgroundColor": "red"

}

})

校验生成的 rn 样式属性的正确性。

生成 rn 样式文件xx_styles.js。

在转换后我们可以发现,原本引入的是 xx.scss 样式文件,现在变为了 import xxStyleSheet from "./xx_styles"。那么这一步是在哪做的呢?

其实是在上一步提到的,再次重新生成 ast 的过程中,设置 babel-plugin-transform-jsx-to-stylesheet 插件起的作用。

原始:

import './index.scss'

转换后:

import indexStyleSheet from "./index_styles";

var _styleSheet = indexStyleSheet;

;

生成工程文件

生成如下文件:

index.js,入口文件,添加下列代码。

import {AppRegistry} from 'react-native';

import App from './app';

import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

app.json,工程配置

主要是将 package.json 中的 name 值取出,放入到 app.json中。

{

"name": "myApp"

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: taro-plugin-tailwind是一个用于Taro开发框架的插件,它结合了Tailwind CSS和Taro框架的功能,旨在提供更便捷、高效的开发体验。 Tailwind CSS是一个功能强大、可定制的CSS框架,它通过提供一系列预定义的样式类,使开发者能够快速构建出丰富多样的UI界面。而Taro是一款跨平台的前端开发框架,它可以同时构建小程序、H5和React Native等多个平台的应用。 taro-plugin-tailwind的作用就是将这两者有机地结合在一起,让开发者在使用Taro开发项目时能够直接使用Tailwind CSS提供的各种样式类,从而节省编写繁琐CSS样式的时间。 使用taro-plugin-tailwind,我们只需要在Taro项目中安装并配置好该插件,然后就可以在项目中使用Tailwind CSS的样式类来定义组件的样式。例如,我们可以使用类似"bg-blue-500"、"text-white"这样的样式类来设置组件的背景颜色和文字颜色。 此外,taro-plugin-tailwind还提供了一些自定义配置的选项,允许开发者根据具体项目的需求进行样式配置和扩展。这使得我们可以根据项目需要添加自定义的样式类或修改现有的样式类,进一步满足项目的设计需求。 总之,taro-plugin-tailwind是一个帮助开发者将Tailwind CSS快速应用到Taro项目中的插件,它简化了样式开发流程,提高了开发效率,让我们可以更专注于项目的逻辑实现。 ### 回答2: taro-plugin-tailwind是一个适用于Taro前端开发框架的插件,它允许开发者在Taro项目中使用Tailwind CSS来简化样式开发流程。 Tailwind CSS是一个功能强大的工具集,它提供了一系列的CSS类名,开发者可以通过组合这些类名来构建出复杂的样式。使用Tailwind CSS能够大大提高开发效率,减少样式代码量,并且能够保持代码的可读性和可维护性。 taro-plugin-tailwind的使用非常简单,只需要在Taro项目中安装该插件,然后在配置文件中进行相应的配置即可。该插件会自动将Tailwind CSS的类名转换为对应的样式。 通过使用taro-plugin-tailwind,开发者可以在Taro项目中使用大量的预定义样式类名,如颜色、背景、边框、文本样式等,可以轻松实现样式的定制化和重用。同时,该插件还支持自定义配置,开发者可以根据项目需求进行个性化的设置。 总之,taro-plugin-tailwind是一个非常实用的插件,它使得在Taro项目中使用Tailwind CSS更加方便和高效,能够帮助开发者快速构建出漂亮而且响应式的界面。无论是新项目还是现有项目,都可以考虑使用taro-plugin-tailwind来加速开发进程。 ### 回答3: taro-plugin-tailwind是一个为Taro框架提供的Tailwind CSS的插件。Taro是一个跨平台的前端开发框架,可以使用一套代码开发多个平台的应用程序,包括小程序、H5、React Native等。 Tailwind CSS是一个高度可定制的CSS框架,它通过将原子类(例如m-4、p-2)组合来构建样式,可以快速而灵活地创建各种各样的界面。Taro-plugin-tailwind的目的就是将Tailwind CSS集Taro框架中,提供更强大的样式处理能力。 使用taro-plugin-tailwind可以让开发者更轻松地在Taro应用中使用Tailwind CSS,省去了手动配置的繁琐过程。只需要在Taro项目中安装这个插件,并在项目的配置文件中进行相应的配置,即可开始使用Tailwind CSS样式。 通过taro-plugin-tailwind,开发者可以使用Tailwind CSS的所有特性,如响应式布局、自定义颜色、间距、阴影等。可以通过直接引用Tailwind CSS的类名,或者使用插件提供的自定义组件,来实现所需的样式效果。 总之,taro-plugin-tailwind是一个集了Tailwind CSS的Taro插件,通过使用这个插件,开发者可以更方便地在Taro应用中使用Tailwind CSS,快速构建出具有各种样式效果的界面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值