• iOS端创建ReactNative容器第一步:打出jsbundle和资源包


    react-native的打包流程是通过执行react-native bundle指令进行的。
     
    添加构建指令
    修改RN项目中的package.json文件,先其中添加构建命令build-release-ios和build-debug-ios
    "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest",
    "build-release-ios": " react-native bundle --platform ios --entry-file index.js --bundle-output ./dest/bundle/index.jsbundle --assets-dest ./dest/bundle --dev false ",
    "build-debug-ios": " react-native bundle --platform ios --entry-file index.js --bundle-output ./dest/bundle/index.jsbundle --assets-dest ./dest/bundle --dev true "
    },
    说明如下;
    react-native的打包是使用的命令react-native bundle, 然后再根据需要添加对应的参数。
    --entry-file ,ios或者android打包入口的js文件名称,比如index.js(如果要根据不同的平台添加不同的功能,则需要将安卓和iOS的打包入口分开创建index.ios.js, index.android.js)
    --platform ,平台名称(ios或者android)
    --dev ,设置为false的时候表示为发布包,true为测试包,发布包会对JavaScript代码进行优化处理。
    --bundle-output, 生成的jsbundle文件的名称,比如 ./dest/bundle/index.jsbundle
    --assets-dest 图片以及其他资源存放的目录,比如./dest/bundle, 注意这里导出的资源是在jsbundle中通过引用使用的资源。
     
    开始打包
    打开RN项目,执行下面的打包指令进行打包
    npm run build-release-ios
    或者
    yarn build-release-ios
    

    指令执行完成后,打包的产物是放置在了./dest/bundle/目录之下

    0
     
    内置打包产物
    将jsbundel包和assets资源包拖到项目中,放置到同一个目录下。
    0
    然后修改jsbundle的读取位置,将从服务器读取改成从本地读取。
    - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
    {
    
      return [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"jsbundle"];
    
    //  return [self getBundleURL];
    }
    
    - (NSURL *)getBundleURL
    {
    #if DEBUG
      return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
    #else
      return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    #endif
    }
    

     在iOS项目中,根据不同的业务类型加载不同的模块名称

      RNContainerController * containerVC = [[RNManager sharedInstance] loadWithModuleName:@"News" initialProps:@{}];
      [self presentModalViewController:containerVC animated:YES];
    

     

    0
     
    JSBundle产物介绍
     
    RN 通过执行react-native bundle打包命令得到产物JSBundle。
    "build-debug-ios": " react-native bundle --platform ios --entry-file index.js --bundle-output ./dest/bundle/index.jsbundle --assets-dest ./dest/bundle --dev true "
    

    因为我们平时写的RN模块中会使用到图片,git,json文件这些资源,所以打出的产物也包含了js文件和资源文件。

     
    产物JSBundle内容组成
    //1.全局变量定义
    var __BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),__DEV__=true,process=this.process||{},__METRO_GLOBAL_PREFIX__='',__requireCycleIgnorePatterns=[/(^|\/|\\)node_modules($|\/|\\)/];process.env=process.env||{};process.env.NODE_ENV=process.env.NODE_ENV||"development";
    //2.require, clear全局函数声明
    (function (global) {
      "use strict";
    
      global.__r = metroRequire;
      global[`${__METRO_GLOBAL_PREFIX__}__d`] = define;
      global.__c = clear;
      global.__registerSegment = registerSegment;
      var modules = clear();
      var EMPTY = {};
      var CYCLE_DETECTED = {};
      var _ref = {},
        hasOwnProperty = _ref.hasOwnProperty;
      if (__DEV__) {
        global.$RefreshReg$ = function () {};
        global.$RefreshSig$ = function () {
          return function (type) {
            return type;
          };
        };
      }
    })()
    //3.RN模块定义(包括RN框架自己的,第三方库的,用户自定义的)
    __d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) {
    xxx
    xxx
    xxx
    },544,[1,262,306,21,50,91],"node_modules/react-native/Libraries/NewAppScreen/components/ReloadInstructions.js");
    __d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) {
      var _interopRequireDefault = _$$_REQUIRE(_dependencyMap[0], "@babel/runtime/helpers/interopRequireDefault");
      Object.defineProperty(exports, "__esModule", {
        value: true
      });
      exports.default = News;
      var _react = _interopRequireDefault(_$$_REQUIRE(_dependencyMap[1], "react"));
      var _reactNative = _$$_REQUIRE(_dependencyMap[2], "react-native");
      var _jsxRuntime = _$$_REQUIRE(_dependencyMap[3], "react/jsx-runtime");
      var _jsxFileName = "/Users/admin/Documents/MyFile/react-native-container/src/News.tsx";
      function News(params) {
        return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
          children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.SafeAreaView, {
            children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
              style: {
                color: 'red'
              },
              children: "Hello ReactNative"
            }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Switch, {
              children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
                children: "\u5F00\u5173"
              })
            })]
          })
        });
      }
    },545,[1,50,2,91],"src/News.tsx");
    __d(function(global, require, _importDefaultUnused, _importAllUnused, module, exports, _dependencyMapUnused) {
      module.exports = {
      "name": "AwesomeProject",
      "displayName": "AAAAA"
    }
    ;
    },546,[],"app.json");
    //4.require方法调用
    __r(54);
    __r(0);
    

    从上面内容可知,jsbundle有四部分组成:

    1.var 全局变量声明,包括对当前运行环境的定义,bundle 的启动时间、Process进程环境相关信息;
    2.在(function() { })() 闭包中定义了对 define(__d)、 require(__r)、clear(__c) 的支持,以及 module(react-native及第三方dependences依赖的module) 的加载逻辑;
    3.使用__d定义的模块信息,包括RN框架源码 js 部分、自定义js代码部分、图片资源信息,供 require 引入使用;
    4.通过require执行模块代码,找到 __d 定义的代码块并执行,其中require中的数字即为 __d定义行中最后出现的那个数字。
     
     
     
     
     
     
  • 相关阅读:
    ​【原创】基于SSM的物流管理系统(物流管理系统毕业设计源代码)
    PCL_点云分割_基于法线微分分割
    【UE 材质】制作加载图案(2)
    AI&机器学习笔试题
    python中的异常处理try-except-else-finally
    小红书商品详情API接口(商品详情页面数据接口)
    Node.js的POST请求与响应编程
    Transformer【第五章】
    Kali : 安装Google Chrome 浏览器和ChromeDriver
    java异步
  • 原文地址:https://www.cnblogs.com/zhou--fei/p/18075834