ReactNative - 打离线包 (二) 携程 Moles-Packer 框架命令打包

ReactNative - 打离线包 (二) 携程 Moles-Packer 框架命令打包

Moles-Packer 是由携程框架团队研发的,与携程 Moles 框架配套使用的 React Native 打包和拆包工具,同时支持原生的 React Native 项目。

安装

执行命令进行 Moles-Packer 的安装

npm install -g moles-packer

Moles Packer 安装完成后,将创建两个命令:

  • moles-packer
    用于项目构建,可编译业务代码并将其打包,也可同时创建公包。

  • moles-packer-common
    仅用于创建公包及相应的元数据文件。

可通过命令进行 moles-packer 版本的查询

moles-packer -v
moles-packer-common -v

上述操作步骤如下:


具体操作步骤如下
具体操作步骤如下

Moles-Packer 参数详解

Options

  --bundle [<bundle.js>] 指示将构建结果合并输出,该文件将被保存在 --output 指定的目录中, 默认情况下 bundle 中不包含公包模块,除非使用 --standalone 选项。
  --common-input 指定公包目录,并在构建过程中使用该目录中的预制公包及其元数据文件。
  --common-modules 指定公包中所包含的模块,多个模块之间使用逗号分隔。
  --common-output 指定公包输出目录。当选项值是相对路径时,如果以 . 或 .. 起始,则相对于当前工作目录;否则认为相对于 --output 选项所指定的输出目录。
  --dev 开发模式下构建的代码,在运行时可以输出更多的调试信息。
  --entry 指定入口文件名称。 默认为 index.js
  --exec-on-required 当且仅当模块首次被实际使用时,执行其相应的定义程序。
  --input 指定项目目录。默认为当前目录
  --minify 默认情形下,Moles Packer 将保持输出代码的可读性,不对其进行压缩和混淆。
  --output 指定输出目录。默认为./build,如果该目录不存在,Moles Packer 会自动创建。 如果该目录已经存在,其中的文件有可能被覆盖。
  --platform 指定构建输出结果适用的操作系统平台。如: ios
  --standalone 是否输出可独立运行的 bundle 文件。该选项应与 --bundle 和 --platform 选项配合使用。

Moles-Packer 打包准备

Moles-Packer 对 React Native 版本有要求

React Native 版本要求

由上可知,Moles-Packer暂时还不支持 React Native 的 0.38.0 以上的版本, 目前 React Native 的最新版本为 0.40.0 。

0.38.0使用moles-packer

因此,构建 React Native 工程需要使用 0.37.0 以下的版本。

Moles-Packer 打包

首先你得有个 React Native 的工程。这里以空工程打包为例:
1.创建适合 Moles-Packer 的 React Native 版本

react-native init ReactNativeV37 --version 0.37.0 

2.执行打包命令

moles-packer --entry index.ios.js --platform ios --standalone --output ./ios/build --verbose 

3.查看执行完打包命令后的结果

[MOLES_PACKER] -- options parsed --

  name            value                                              
  --------------  ---------------------------------------------------
  base            "/Users/QCL/ReactNative/ReactNativeV37"   
  bundle          true                            
  commonOutput    "BASE/ios/build/moles.common"   
  dev             false                           
  entry           "BASE/index.ios.js"             
  execOnRequired  false                           
  input           "BASE/"                         
  isCLI           true                            
  metaOutput      "BASE/ios/build/moles.meta.json"
  minify          false                           
  output          "BASE/ios/build"                
  platform        "ios"                                     
  single          false                           
  standalone      true                            
  verbose         true                            

[MOLES_PACKER] -- Process common bundle --
[COMMON] Create common bundle ( ios )
[2017-1-16 14:25:15] <START> Initializing Packager
[2017-1-16 14:25:15] <START> Building in-memory fs for JavaScript
[2017-1-16 14:25:15] <END>   Building in-memory fs for JavaScript (164ms)
[2017-1-16 14:25:15] <START> Building Haste Map
[2017-1-16 14:25:15] <END>   Building Haste Map (96ms)
[2017-1-16 14:25:15] <END>   Initializing Packager (333ms)
[2017-1-16 14:25:15] <START> Transforming modules
[2017-1-16 14:25:15] <END>   Transforming modules (385ms)
bundle: start
bundle: finish
bundle: Writing bundle output to: .moles/common.ios.jsbundle
bundle: Writing sourcemap output to: .moles/common.ios.sourcemap.json
bundle: Done writing bundle output
bundle: Done writing sourcemap output
[COMMON] Re-create common bundle ( ios )
[COMMON] Minify common bundle ( ios )
[COMMON] COMMON BUNDLE: /Users/QCL/ReactNative/ReactNativeV37/ios/build/moles.common/common.ios.jsbundle ( ios )
[COMMON] COMMON META: /Users/QCL/ReactNative/ReactNativeV37/ios/build/moles.common/common.ios.json ( cross )
[MOLES_PACKER] Common modules ready.
[MOLES_PACKER] -- Process business code --
[SOURCE] index.ios.js ( entry )
[BUNDLE] - ( top )
[BUNDLE] index.ios.js ( entry )
[BUNDLE] - ( bottom )
[TARGET] index.ios.jsbundle ( bundle )
[TARGET] moles.meta.json ( meta )
[MOLES_PACKER] -- end --
[MOLES_PACKER] See /Users/QCL/ReactNative/ReactNativeV37/ios/build
目录层级

4.将 index.ios.jsbundle 引入工程

index.ios.jsbundle

5.修改 AppDelegate.m 中的源码

NSURL *jsCodeLocation;

// jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
jsCodeLocation = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"index.ios.jsbundle" ofType:nil]];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                    moduleName:@"ReactNativeV37"
                                             initialProperties:nil
                                                 launchOptions:launchOptions];

6.如果要离线真机测试或打包上传应用, 需要进行如下修改

因为 ReactNative 自带 Chrome 的 Debug 模式, 因此需要修改成 Release ,来关闭掉 Debug 模式


修改Release

7.打包上传或真机调试,与iOS工程无异。
具体步骤如下:


打包过程
打包过程

打包过程中的问题

问题1: 找不到的 node-haste 模块

[MOLES_PACKER] -- Process common bundle --
module.js:474
throw err;
       ^

Error: Cannot find module 'node-haste/lib/DependencyGraph/docblock.js'
at Function.Module._resolveFilename (module.js:472:15)
at Function.Module._load (module.js:420:25)
at Module.require (module.js:500:17)
at require (internal/module.js:20:19)
at _create_common (/usr/local/lib/node_modules/moles-packer/lib/packCommon.js:37:17)
at _ME (/usr/local/lib/node_modules/moles-packer/lib/packCommon.js:282:18)
at _ME (/usr/local/lib/node_modules/moles-packer/lib/pack.js:22:22)
at Object. (/usr/local/lib/node_modules/moles-packer/bin/pack.js:4:1)
at Module._compile (module.js:573:32)
at Object.Module._extensions..js (module.js:582:10)

解决方案

npm install -g node-haste

问题2:找不到的 transform-es5-property-mutators 插件

[MOLES_PACKER] Common modules ready.
[MOLES_PACKER] -- Process business code --
[SOURCE] index.ios.js ( entry )
start ... react / es2015 ... /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:176
throw new ReferenceError(messages.get("pluginUnknown", plugin, loc, i, dirname));
^

ReferenceError: Unknown plugin "transform-es5-property-mutators" specified in "base" at 0, attempted to resolve relative to "/Users/QCL/ReactNative/v031"
at /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:176:17
at Array.map (native)
at Function.normalisePlugins (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:154:20)
at OptionManager.mergeOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:229:36)
at OptionManager.init (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:374:12)
at File.initOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:216:65)
at new File (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:139:24)
at Pipeline.transform (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
at _transform_react (/usr/local/lib/node_modules/moles-packer/lib/transform.js:137:24)
at _one (/usr/local/lib/node_modules/moles-packer/lib/transform.js:110:9)

解决方案

npm install -g babel-plugin-transform-es5-property-mutators

问题3: 找不到的 es2015 模块

[MOLES_PACKER] -- Process business code --
[SOURCE] index.ios.js ( entry )
start ... react / es2015 ... /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:334
        throw e;
        ^

Error: Couldn't find preset "es2015" relative to directory "/Users/QCL/ReactNative/ReactNativeV37"
    at /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:299:19
    at Array.map (native)
    at OptionManager.resolvePresets (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:270:20)
    at OptionManager.mergePresets (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:259:10)
    at OptionManager.mergeOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:244:14)
    at OptionManager.init (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:374:12)
    at File.initOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:216:65)
    at new File (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:139:24)
    at Pipeline.transform (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
    at _transform_react (/usr/local/lib/node_modules/moles-packer/lib/transform.js:137:24)

解决方案:

npm install babel-preset-es2015

问题4: 找不到 stage-0 模块

[MOLES_PACKER] -- Process business code --
[SOURCE] index.ios.js ( entry )
start ... react / es2015 ... /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:334
        throw e;
        ^

Error: Couldn't find preset "stage-0" relative to directory "/Users/QCL/ReactNative/ReactNativeV37"
    at /usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:299:19
    at Array.map (native)
    at OptionManager.resolvePresets (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:270:20)
    at OptionManager.mergePresets (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:259:10)
    at OptionManager.mergeOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:244:14)
    at OptionManager.init (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:374:12)
    at File.initOptions (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:216:65)
    at new File (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/file/index.js:139:24)
    at Pipeline.transform (/usr/local/lib/node_modules/moles-packer/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
    at _transform_react (/usr/local/lib/node_modules/moles-packer/lib/transform.js:137:24)

解决方案:

npm install babel-preset-stage-0

问题3和问题4的
解决方案二:

使用 subl 打开 package.json

subl package.json

在 packjson.json 的 devDependencies 中添加如下代码:

"babel-preset-stage-0": "6.16.0",
"babel-preset-es2015": "6.18.0"

添加完成后,如下:

{
  "name": "ReactNativeV37",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "15.3.2",
    "react-native": "0.37.0"
  },
  "jest": {
    "preset": "jest-react-native"
  },
  "devDependencies": {
    "babel-jest": "18.0.0",
    "babel-preset-react-native": "1.9.1",
    "jest": "18.1.0",
    "jest-react-native": "18.0.0",
    "react-test-renderer": "15.3.2",
    "babel-preset-stage-0": "6.16.0",
    "babel-preset-es2015": "6.18.0"
  }
}

最后执行

npm install

参考文章

我在 Github 提的 issues
从零开始,使用 Moles Packer
React Native 版本
CtripMoles 的简书

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容