RN Metro打包流程

参考:react-native bundle 到 bundle 生成到底发生了什么(metro 打包流程简析)

流程

metro 打包的整个流程大致分为:

  • 命令参数解析
  • metro 打包服务启动
  • 打包 js 和资源文件
  • 解析,转化和生成
  • 停止打包服务

在这里插入图片描述

涉及到的包
  • @react-native-community(react-native bundle命令封装处)解析命令参数
  • metro中进行解析、转换、生成

metro-source-map/src/source-map.js文件:

const SourceMap = require("source-map");
function toBabelSegments(sourceMap) {
  const rawMappings = [];
  new SourceMap.SourceMapConsumer(sourceMap).eachMapping(map => {
    rawMappings.push({
      generated: {
        line: map.generatedLine,
        column: map.generatedColumn
      },
      original: {
        line: map.originalLine,
        column: map.originalColumn
      },
      source: map.source,
      name: map.name
    });
  });
  return rawMappings;
}

node运行source-map.js脚本可以定位到错误代码(x行x列),大概像这样子:
在这里插入图片描述

react-native bundle 打包命令

执行react-native bundle 打包命令会生成一个android.main.bundle文件和android.main.bundle.map

react-native bundle \
  --dev false \
  --platform android \
  --entry-file index.android.js \
  --bundle-output android.main.bundle \
  --sourcemap-output android.main.bundle.map

打包后的文件:
在这里插入图片描述

命令参数:

--dev : false: product包   true: dev包

--platform: 对应的平台

--entry-file:入口文件

--config: 额外配置

--bundle-output:生成的bundle文件输出位置

--assets-dest: 图片等资源输出的位置

--sourcemap-output: 映射文件输出的位置
sourcemap文件格式
{
    version : 3,
    file: "out.js",
    sourceRoot : "",
    sources: ["foo.js", "bar.js"],
    names: ["src", "maps", "are", "fun"],
    mappings: "AAgBC,SAAQ,CAAEA"
}

整个文件就是一个JavaScript对象,可以被解释器读取。它主要有以下几个属性:

  • version:Source map的版本,目前为3。

  • file:转换后的文件名。

  • sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。

  • sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。

  • names:转换前的所有变量名和属性名。

  • mappings:记录位置信息的字符串,下文详细介绍。

具体sourcemap格式参考:JavaScript Source Map 详解

区别于Bundle文件格式(本质是一个string):

// var声明层

var __BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),__DEV__=false,process=this.process||{};process.env=process.env||{};process.env.NODE_ENV=process.env.NODE_ENV||"production";

//polyfill层

!(function(r){"use strict";r.__r=o,r.__d=function(r,i,n){if(null!=e[i])return;var o={dependencyMap:n,factory:r,hasError:!1,importedAll:t,importedDefault:t,isInitialized:!1,publicModule:{exports:{}}};e[i]=o}

...
// 模型定义层
__d(function(g,r,i,a,m,e,d){var n=r(d[0]),t=r(d[1]),o=n(r(d[2])),u=r(d[3]);t.AppRegistry.registerComponent(u.name,function(){return o.default})},0,[1,2,402,403]);
....
__d(function(a,e,t,i,R,S,c){R.exports={name:"ReactNativeSSR",displayName:"ReactNativeSSR"}},403,[]);

// require层
__r(93);
__r(0);

sentry代码监控

sentry是一个基于Django构建的现代化的实时事件日志监控、记录和聚合平台,主要用于如何快速的发现故障。

sentry上传sourcemap文件命令(sentry-cli):React Native集成Sentry之SourceMap

sentry-cli releases -o pika -p react-native files com.reactnative_sentry_demo@test+3  upload-sourcemaps \
--dist 3 \
--url-prefix "app:///" \
--rewrite path/to/index.android.bundle path/to/index.android.bundle.map

sentry介绍:Sentry介绍与使用

基于sentry sourcemap的一个优化:
在这里插入图片描述

Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐