ReactNative系列之三十二Bundle的結構
阿新 • • 發佈:2019-02-20
bundle結構分析
包括三部分:
- polyfills : 最早執行的一些function,宣告es語法新增的介面,定義模組宣告方法
__d
等 - module difinitations : 模組宣告,以
__d
開頭,每一行代表一個JS的定義 - require calls : 執行
InitializeCore
和Entry File
,最後一行require(0);
1、polyfills部分
1)自執行匿名函式:
- 常見格式:(function() { /* code */ })();
- 解釋:包圍函式(function(){})的第一對括號向指令碼返回未命名的函式,隨後一對空括號立即執行返回的未命名函式,括號內為匿名函式的引數。
- 作用:可以用它建立名稱空間,只要把自己所有的程式碼都寫在這個特殊的函式包裝內,那麼外部就不能訪問,除非你允許(變數前加上window,這樣該函式或變數就成為全域性)。各JavaScript庫的程式碼也基本是這種組織形式。
總結一下,執行函式的作用主要為 匿名 和 自動執行,程式碼在被解釋時就已經在運行了。
2)定義模組宣告方法__d及require
!(function(r){ 'usestrict';r.require=t, r.__d=function(r, t, i){ if(tine)return;e[ t ]={ dependencyMap: i, exports: void0, factory: r, hasError: !1, isInitialized: !1 } };vare=Object.create(null);functiont(t){ varn=t, o=e[ n ];returno&&o.isInitialized?o.exports: (function(e, t){ if(!i&&r.ErrorUtils){ i=!0;varn=void0;try{ n=a(e, t) }catch(e){ r.ErrorUtils.reportFatalError(e) }returni=!1, n }returna(e, t) })(n, o) }t.async=function(r){ returnPromise.resolve().then(function(){ returnt(r) }) };vari=!1;varn=16, o=-1>>>n;functiona(i, a){ varu=r.nativeRequire;!a&&u&&(u(i&o, i>>>n), a=e[ i ]);if(!a)throwError('Requiringunknownmodule"'+i+'".');if(a.hasError)throw(function(r, e){ returnError('Requiringmodule"'+r+'", whichthrewanexception: '+e) })(i, a.error);a.isInitialized=!0;varc=a.exports={ }, s=a, d=s.factory, f=s.dependencyMap;try{ varl={ exports: c };returnd(r, t, l, c, f), a.factory=void0, a.dependencyMap=void0, a.exports=l.exports }catch(r){ throwa.hasError=!0, a.error=r, a.isInitialized=!1, a.exports=void0, r } } })('undefined'!=typeofglobal?global: 'undefined'!=typeofself?self: this);'undefined'!=typeofglobal?global: 'undefined'!=typeofself&&self, Object.assign=function(e, n){ for(varf=1;f<arguments.length;f++){ varl=arguments[ f ];if(null!=l)for(varoinl)e[ o ]=l[ o ] }returne };
2、__d()模組定義部分
1)包括RN的原始碼js部分
2)自定義js部分
3)自定義圖片資源資訊
__d(function(e,n,t,o){'use strict';Object.defineProperty(o,"__esModule",{value:!0}),o.getName=function(){return'from common module! My name is '+this._name},o.setName=function(e){this._name=e},n('node_modules/react/index.js'),n('node_modules/react-native/Libraries/react-native/react-native-implementation.js')},"common/common.js"); __d(function(e,s,t,a){t.exports=s('node_modules/react-native/Libraries/Image/AssetRegistry.js').registerAsset({__packager_asset:!0,httpServerLocation:"/assets/subB",width:121,height:91,scales:[1],hash:"fbb224ba9a95abed93bd1c3281de9279",name:"linux",type:"jpeg"})},"subB/linux.jpeg");
__d實際上是metro-bundle/Resolver/polyfills/require.js檔案中的define方法
3、require起始js檔案
可以單獨分析下InitializeCore.js,很多RN初始化的工作
;require("node_modules/react-native/Libraries/Core/InitializeCore.js");
;require("subA/subA.js");
require()實際上是metro-bundle/Resolver/polyfills/require.js檔案中的require方法