11const esprima = require ( 'esprima' ) ;
22const estraverse = require ( 'estraverse' ) ;
33const escodegen = require ( 'escodegen' ) ;
4- const _ = require ( 'lodash' ) ;
54
65// declare functions to insert
76function useReducerReplacement ( ) {
@@ -18,7 +17,7 @@ function useReducerReplacement() {
1817 } ) ;
1918 return newState ;
2019 }
21- return dispatcher . useReducer ( reducerWithTracker , initialArg , init ) ;
20+ return dispatcher . useReducer ( reducerWithTracker , initialState , initialAction ) ;
2221}
2322
2423function commitAllHostEffectsReplacement ( ) {
@@ -35,27 +34,27 @@ function commitAllHostEffectsReplacement() {
3534 }
3635 recordEffect ( ) ;
3736
38- let { effectTag} = nextEffect ;
37+ const { effectTag } = nextEffect ;
3938
4039 if ( effectTag & ContentReset ) {
4140 commitResetTextContent ( nextEffect ) ;
4241 }
4342
4443 if ( effectTag & Ref ) {
45- let current$$1 = nextEffect . alternate ;
44+ const current$$1 = nextEffect . alternate ;
4645 if ( current$$1 !== null ) {
4746 commitDetachRef ( current$$1 ) ;
4847 }
4948 }
5049
51- let primaryEffectTag = effectTag & ( Placement | Update | Deletion ) ;
50+ const primaryEffectTag = effectTag & ( Placement | Update | Deletion ) ;
5251 switch ( primaryEffectTag ) {
5352 case Placement :
5453 {
5554 // editbyme
5655 timeTravelLList . append ( {
57- primaryEffectTag : 'PLACEMENT' ,
58- effect : _ . cloneDeep ( nextEffect ) ,
56+ primaryEffectTag : 'PLACEMENT' ,
57+ effect : _ . cloneDeep ( nextEffect ) ,
5958 } ) ;
6059
6160 commitPlacement ( nextEffect ) ;
@@ -67,7 +66,7 @@ function commitAllHostEffectsReplacement() {
6766 {
6867 commitPlacement ( nextEffect ) ;
6968 nextEffect . effectTag &= ~ Placement ;
70- let _current = nextEffect . alternate ;
69+ const _current = nextEffect . alternate ;
7170 commitWork ( _current , nextEffect ) ;
7271 break ;
7372 }
@@ -80,7 +79,7 @@ function commitAllHostEffectsReplacement() {
8079 current : _ . cloneDeep ( nextEffect . alternate ) ,
8180 } ) ;
8281
83- let _current2 = nextEffect . alternate ;
82+ const _current2 = nextEffect . alternate ;
8483 commitWork ( _current2 , nextEffect ) ;
8584 break ;
8685 }
@@ -103,20 +102,21 @@ function commitAllHostEffectsReplacement() {
103102 resetCurrentFiber ( ) ;
104103 }
105104}
106- // regex method signatures
107- const uRsig = new RegExp ( / \b ( u s e R e d u c e r ) \b \( r e d u c e r , i n i t i a l A r g , i n i t \) / ) ;
108- const cAHEsig = new RegExp ( / \b ( f u n c t i o n ) \b \s \b ( c o m m i t A l l H o s t E f f e c t s ) \b \( \) / , 'g' ) ;
109105
110- // get replacer method bodies
106+ // method names
107+ const USEREDUCER = 'useReducer' ;
108+ const COMMITALLHOSTEFFECTS = 'commitAllHostEffects' ;
109+ // library key inside of bundle
110+ const reactLibraryPath = './node_modules/react/cjs/react.development.js' ;
111+ const reactDOMLibraryPath = './node_modules/react-dom/cjs/react-dom.development.js' ;
112+ // get replacer method
111113let injectableUseReducer = esprima . parseScript ( useReducerReplacement . toString ( ) ) ;
112- let injectableUseReducerString = escodegen . generate ( injectableUseReducer . body [ 0 ] . body ) ;
113114
114115let injectableCommitAllHostEffects = esprima . parseScript ( commitAllHostEffectsReplacement . toString ( ) ) ;
115- let injectableCommitAllHostEffectsString = escodegen . generate ( injectableCommitAllHostEffects . body [ 0 ] . body ) ;
116116
117117// traverse ast to find method and replace body with our node's body
118118function traverseTree ( replacementNode , functionName , ast ) {
119- console . log ( 'traverse called' ) ;
119+ console . log ( 'unbundled traverse called' ) ;
120120 estraverse . replace ( ast , {
121121 enter ( node ) {
122122 if ( node . type === 'FunctionDeclaration' ) {
@@ -128,55 +128,54 @@ function traverseTree(replacementNode, functionName, ast) {
128128 } ,
129129 } ) ;
130130}
131- function stringParser ( string , newBody , methodSig ) {
132- let stack = [ ] ;
133- const foundMethod = methodSig . test ( string ) ;
134- let oldBody = '' ;
135- let output ;
136- for ( let i = methodSig . lastIndex ; i < string . length ; i ++ ) {
137- if ( foundMethod ) {
138- if ( string [ i ] === '{' ) {
139- stack . push ( string [ i ] ) ;
140- }
141- if ( stack . length > 0 && stack [ stack . length - 1 ] === '{' && string [ i ] === '}' ) {
142- stack . pop ( ) ;
143- oldBody += string [ i ] ;
144- output = string . replace ( oldBody , newBody ) ;
145- break ;
146- }
147- if ( stack . length > 0 ) {
148- oldBody += string [ i ] ;
131+
132+ function traverseBundledTree ( replacementNode , functionName , ast , library ) {
133+ estraverse . traverse ( ast , {
134+ enter ( node ) {
135+ if ( node . key && node . key . value === library ) {
136+ if ( node . value . body . body [ 1 ] . type === 'ExpressionStatement' ) {
137+ if ( node . value . body . body [ 1 ] . expression . callee . name === 'eval' ) {
138+ // create new ast
139+ const reactLib = esprima . parseScript ( node . value . body . body [ 1 ] . expression . arguments [ 0 ] . value ) ;
140+ estraverse . traverse ( reactLib , {
141+ enter ( libNode ) {
142+ if ( libNode . type === 'FunctionDeclaration' ) {
143+ if ( libNode . id . name === functionName ) {
144+ libNode . body = replacementNode . body [ 0 ] . body ;
145+ console . log ( 'From parser. REPLACING body!' , libNode . id . name ) ;
146+ }
147+ }
148+ } ,
149+ } ) ;
150+ node . value . body . body [ 1 ] . expression . arguments [ 0 ] . value = escodegen . generate ( reactLib ) ;
151+ node . value . body . body [ 1 ] . expression . arguments [ 0 ] . raw = JSON . stringify ( escodegen . generate ( reactLib ) ) ;
152+ console . log ( 'arguments replaced' ) ;
153+ }
154+ }
149155 }
150- }
151- }
152- return output ;
156+ } ,
157+ } ) ;
153158}
159+
154160const parseAndGenerate = ( codeString ) => {
155161 if ( codeString . search ( 'react' ) !== - 1 ) {
156- let ast ;
157- try {
158- ast = esprima . parseModule ( codeString ) ;
159- } catch ( error ) {
160- // esprima throws parsing error webpack devtool setting generates code
161- console . log ( 'unable to use esprima parser' ) ;
162- codeString = stringParser ( codeString , injectableUseReducerString , uRsig ) ;
163- codeString = stringParser ( codeString , injectableCommitAllHostEffectsString , cAHEsig ) ;
164- return codeString ;
162+ const ast = esprima . parseModule ( codeString ) ;
163+ // Webpack bundle is wrapped in function call
164+ if ( ast . body [ 0 ] . expression . type === 'CallExpression' ) {
165+ traverseBundledTree ( injectableUseReducer , USEREDUCER , ast , reactLibraryPath ) ;
166+ traverseBundledTree ( injectableCommitAllHostEffects , COMMITALLHOSTEFFECTS , ast , reactDOMLibraryPath ) ;
167+ } else {
168+ // parse react-dom code
169+ injectableCommitAllHostEffects = esprima . parseScript ( commitAllHostEffectsReplacement . toString ( ) ) ;
170+ traverseTree ( injectableCommitAllHostEffects , 'commitAllHostEffects' , ast ) ;
171+
172+ // parse react code
173+ injectableUseReducer = esprima . parseScript ( useReducerReplacement . toString ( ) ) ;
174+ traverseTree ( injectableUseReducer , 'useReducer' , ast ) ;
165175 }
166- // parse react-dom code
167- injectableCommitAllHostEffects = esprima . parseScript ( commitAllHostEffectsReplacement . toString ( ) ) ;
168- traverseTree ( injectableCommitAllHostEffects , 'commitAllHostEffects' , ast ) ;
169-
170- // parse react code
171- injectableUseReducer = esprima . parseScript ( useReducerReplacement . toString ( ) ) ;
172- traverseTree ( injectableUseReducer , 'useReducer' , ast ) ;
173-
174176 const code = escodegen . generate ( ast ) ;
175177 console . log ( 'returning code.' ) ;
176178 return code ;
177179 }
178- console . log ( 'returning string.' ) ;
179- return codeString ;
180180} ;
181-
182181module . exports = parseAndGenerate ;
0 commit comments