Git Product home page Git Product logo

ctripcorp / crn Goto Github PK

View Code? Open in Web Editor NEW
1.5K 40.0 206.0 140.55 MB

CRN是Ctrip React Native简称,由携程无线平台研发团队基于React Native框架优化,定制成稳定性和性能更佳、也更适合业务场景的跨平台开发框架。

License: MIT License

JavaScript 34.31% HTML 0.24% Java 25.40% C++ 19.90% Makefile 0.10% C 0.22% Objective-C++ 3.90% Objective-C 13.58% Ruby 0.03% CSS 0.01% Assembly 0.12% Shell 0.38% Batchfile 0.01% Starlark 1.82%

crn's Introduction

CRN

CRN是Ctrip React Native简称,由携程无线平台研发团队基于React Native框架优化,定制成稳定性和性能更佳、也更适合业务场景的的跨平台开发框架。

本次开源基于ReactNative 0.59.0, react 16.8.3版本, 开源的主要是性能优化部分, 也是规模化使用RN进行业务开发必须要做的优化。

一、 功能列表

  • 打包支持框架和业务代码拆分
  • 支持框架代码后台预加载
  • 打包支持增量编译(同一模块,两次打包模块ID不变)
  • iOS&Android统一一套打包产物
  • 首屏加载性能统计
  • LazyRequire

二、 如何运行

开源代码中的iOS/Android Demo工程可以运行起来,参考以下操作步骤。

  1. RN运行环境搭建,参考官方文档
  2. 进入iOS目录,使用xcode打开./iOS/CRNDemo/CRNDemo.xcodeproj工程,运行
  3. 进入Android目录,使用Android Studio导入./Android工程,Run

三、 CRN性能数据

以Demo工程为例,运行RN官方tester项目。分别在iPhone 7Plus、iPhone 6、Samsung S6 Edge+手机上测试页面的首屏加载时间,对比图如下。

可见CRN优化后的页面首屏加载时间与优化前RN官方的方式相比在iOS上减少了50%左右,Android上减少了60%左右,优化效果明显。

四、 对官方RN的修改

CRN是基于ReactNative定制的,我们对其Runtime、CLI工具代码,都有调整。 主要改动点包括:

  • 支持拆分之后的包运行, 针对CRN打包格式的nativeRequire实现
  • 增强稳定性,主要是Android平台, 大量的异常处理和保护
  • 跨平台共享一份代码、资源, CRN-CLI内部实现

有兴趣的同学可以研究我们的改造点,具体改造点我们都有相应的注释:

  • iOS - 在iOS目录搜索CRN_OPT宏
  • Android - 在Android目录搜索注释'CRN BEGIN'和'CRN END'
  • CLI - 在packages/crn-cli目录搜索'CRN BEGIN'和'CRN END'

五、 CRN-CLI的使用

以上是开源代码的的工程结构及DEMO运行效果,实际开发过程中,不需要关注这些细节,我们可以直接使用CRN-CLI脚手架进行开发调试和打包。

为了方便使用,我们将该开源的CRN-CLI工具发布到了npmjs.com,安装之后可以直接使用,具体使用参考详情

六、 如何接入

为了方便接入,需首先安装crn-cli, 执行 npm install -g crn-cli 即可

1. 全新工程接入

  • crn-cli init <project-name> 初始化工程,里面包含iOS、Android、JS代码
  • crn-cli run-ios , crn-cli run-android 运行RN工程,进行开发调试
  • crn-cli pack 打包,并将打包产物拷贝到Native工程的webapp目录

2. 现有工程接入

  • JS代码部分

    只需在现有JS入口模块文件如index.js中添加一行模块导出代码即可,示例如下:

//index.js
AppRegistry.registerComponent(appName, () => App);
module.exports = App; //添加此行代码,导出入口模块即可

七、 其它

License

CRN is MIT licensed, as found in the LICENSE file.

crn's People

Contributors

blackwuxin avatar chufengma avatar jimzhao2012 avatar zlpcloud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crn's Issues

热更新支持

CRN自定义的打包方案,理论上应该上不支持code-push热更新的吧,如果要支持热更新,后续CRN会考虑支持吗

关于一点加载细节的请教

我是 Android 开发人员。

有几个问题想要请教一下。

  1. 我能否把整个 crn-cli pack 后的目录当作静态资源用 Git 管理起来,然后页面文件有改动之后 push 覆盖,这样我的客户端始终能请求到最新的页面文件(通过一些适当的缓存策略)。

  2. 能够接手客户端这边的 Okhttp 逻辑实现 “静态页面” 的缓存实现吗?例如通过 Code:304静态页面地址全路径#xxx 这样的方式,而尽量不依靠打包进 assets 文件夹来实现业务页面的实时更新。

谢谢!

请教cachedBridgeList的设计,会存在多个bridge的场景吗?

您好,如题:
注意到 CRNBridgeManager 中的 cachedBridgeList 为数组设计,印象中 RN 中的 bridge 实例不是只会有一个吗?为何使用一个 cacheBridgeList来管理,在分包场景下,每次加载业务bundle时还更新common bridge相关信息并不断调用 prepareBridgeIfNeed接口。
比较困惑这块的逻辑,望解答,谢谢您

about "666666"

image
这个“666666”使用的时候需要什么特殊注意么?我看代码的意思是“业务模块ID应>=666666”。

多业务打包问题

目前提供的打包配置入口如下:
"packConfig": {
"entryFile": "index.js", //打包入口文件
"bundleOutput": "publish", //打包产物输出目录
"packageName": "CRNDemo", //包名
"dev": false //打包环境
}
如果有多个子业务在同一个工程下开发,怎么配置多业务打包的入口呢。
还有,请问这套框架怎么解决原生和RN路由跳转的一些问题。

按照你们官方文档初始化app后添加依赖,会出现打包出错

image

Error: Unable to resolve module `./index` from `/Users/admin/Desktop/code/CRNAPPDEMO2/.__tmp/.`: The module `./index` could not be found from `/Users/admin/Desktop/code/CRNAPPDEMO2/.__tmp/.`. Indeed, none of these files exist:
  * `/Users/admin/Desktop/code/CRNAPPDEMO2/.__tmp/index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)`
  * `/Users/admin/Desktop/code/CRNAPPDEMO2/.__tmp/index/index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)`
    at ModuleResolver.resolveDependency (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:163:15)
    at ResolutionRequest.resolveDependency (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18)
    at DependencyGraph.resolveDependency (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph.js:283:16)
    at /Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/lib/transformHelpers.js:261:42
    at Server.<anonymous> (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/Server.js:1038:41)
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/Server.js:99:24)
    at _next (/Users/admin/Desktop/code/CRNAPPDEMO2/node_modules/react-native/node_modules/metro/src/Server.js:119:9)
    at <anonymous>

1、如果打开预加载,则app会崩溃(可能是因为打包失败,没有读取到jsbundle)
2、在根目录下App.js中,import一个依赖就会报上面的错误,可能是服务在拆包的过程中出错了
3、现在只在android模拟器下测试,发现这个问题,iOS还没看

.jsx file is not resolvable [无法识别jsx文件]

Is this a bug?
Yes, as I can see the error logs, it lists everything except .jsx, .native.jsx, .ios.jsx, .etc

Indeed, none of these files exist:
  * `***/src/app(.native||.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)`

Reproduce
Change any jsx-syntax file‘s extension to .jsx to test
Suggestion
use metro.config.js to apply supported extensions


这是bug吗?
是,错误日志如下,除了jsx全都支持,即使是tsx

Indeed, none of these files exist:
  * `***/src/app(.native||.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)`

如何重现
把任意含jsx的组件后缀改为jsx
建议
使用metro.config.js的配置增加支持

如何在js打包多业务

非常感谢携程的开源。
看了一下crn-cli的代码,目前pack命令只支持生成common+一个业务。如果想要生成一个common+多个业务,应该如何配置js文件和打包呢?

会支持rn和原生分离么

想要实现像h5那样的模式(无需发包):
前端人员只需要把rn页面打包成bundle(带hash),上传到服务器。
原生人员则只需要下载bundle比较hash来进行热更新(无需发包)。

这种的目前可以实现么???

启动服务的问题

你好,我在 Ubuntu 上 init 项目过后,可以直接使用以下命令直接启动服务没?

crn-cli start

我执行过后,提示

[crn-cli]: 正在判断当前输入参数是否合法以及当前目录路径是否合法...
[crn-cli]: 当前输入参数合法!
[crn-cli]: 当前目录路径为: /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo
[crn-cli]: 当前启动的RN服务端口为: 8081
[crn-cli]: 正在判断当前RN服务是否已经启动...
[crn-cli]: 当前RN服务正在启动...
[crn-cli]: 当前写入启动服务脚本...
[crn-cli]: 写入启动服务脚本完成!
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/shared/output/RamBundle/crn-as-assets.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/shared/output/crn-bundle.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/lib/createModuleIdFactory.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/shared/output/RamBundle/as-assets.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/shared/output/bundle.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/ModuleGraph/worker/collectDependencies.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro-config/src/defaults/index.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/shared/output/RamBundle.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/metro/src/lib/polyfills/require.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/react-native/Libraries/polyfills/lazyRequire.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/react-native/Libraries/Image/AssetSourceResolver.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/react-native/Libraries/Image/resolveAssetSource.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/@react-native-community/cli/build/commands/bundle/bundle.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/@react-native-community/cli/build/commands/bundle/buildBundle.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/@react-native-community/cli/build/commands/bundle/bundleCommandLineArgs.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/node_modules/react-native/rn-get-polyfills.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/rn-cli.config.js >文件
成功替换< /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/crn_common_entry.js >文件
[crn-cli]: 正在启动RN服务...
[crn-cli]: 执行以下脚本: /home/lychee/.local/share/Trash/files/CRNDemo/CRNDemo/.__tmp/launchPackager.command
[crn-cli]: 启动RN服务成功!

但是我查看了下,8081 上并没有程序在跑,我也无法访问。

`ctrip.wireless.android:ReactAndroid:0.59.0-01-SNAPSHOT` 中的 `ctrip.crn`为什么不拿出来放在`crnbase`模块中

ctrip.wireless.android:ReactAndroid:0.59.0-01-SNAPSHOT 中有包含两部分:com.facebookctrip.cn,如果com.facebook完全是rn源码的话,为什么不把ctrip.cn拿出来直接放在crnbase模块中,这样就能完全和rn源码解耦了。

我们这边有自己维护一份rn源码,打包成了aar(new-rn),一开始想的方式是 crn依赖new-rn而不是ctrip.wireless.android:ReactAndroid:0.59.0-01-SNAPSHOT ,现在由于ctrip.cn这个package的原因,这样行不通了,有什么方式解决这个问题吗

ContextHolder.context 为空

然后在PackageManager 里的各种引用报错
'java.io.File android.content.Context.getFilesDir()' on a null object reference

Android Runtime接入文档的补充

我已经在我的现有项目接入了。针对文档中不太详细的描述,补充一下,希望携程的大佬们能及时完善一下文档,更方便大家接入。

  • 1.在settings.graldle添加
include ':ReactAndroid',':crnbase'
project(':ReactAndroid').projectDir = new File(rootProject.projectDir, './rnSource/ReactAndroid')

在gradle里引入是 implementation project(':crnbase')不是 implementation project(':base')

  • 2.如果需要通过ReactAndroid来进行编译的话,需要在根目录下的gradle.properties里配置useReactAndroidSource=true,同时配置NDK环境。(但是编译会比较耗时)
  • 3.如果不想要通过ReactAndroid源码来进行编译,就把CRN工程的repo目录拷贝进来,useReactAndroidSource设置为false。同时Android Native项目根目录下gradle allprojects里的repositories里添加
maven {url = "$rootDir/repo" }。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.