@samitouri / QOS-React / commits / a3ba48bf72

Fix browser bundle for AMD (#8374)

* Fix browser bundle for AMD * Final fix for standalone browser build. Much more scientific than the rest so it should stick. * Throw when we can't find code we need to replace.

Paul O’Shannessy committed Nov 22, 2016 at 17:16 UTC a3ba48bf724de4c23d7c32f1b381476bcd3bb6fa
1 file changed +27 -8
grunt/config/browserify.js
+27 -8
@@ -63,7 +63,7 @@ function simpleBannerify(src) {
63 }
64
65 // What is happening here???
66 -// I'm glad you asked. It became really to make our bundle splitting work.
66 +// I'm glad you asked. It became really hard to make our bundle splitting work.
67 // Everything is fine in node and when bundling with those packages, but when
68 // using our pre-packaged files, the splitting didn't work. Specifically due to
69 // the UMD wrappers defining their own require and creating their own encapsulated
@@ -71,19 +71,38 @@ function simpleBannerify(src) {
71 // be smart and looks for top-level requires (even when aliasing to a bundle),
72 // but since we didn't have those, we couldn't require 'react' from 'react-dom'.
73 // But we are already shimming in some modules that look for a global React
74 -// variable. So we write a wrapper around the UMD bundle that browserify creates,
75 -// and define a React variable that will require across Webpack-boundaries or fall
76 -// back to the global, just like it would previously.
74 +// variable. So we replace the UMD wrapper that browserify creates with out own,
75 +// in 2 steps.
76 +// 1. We swap out the browserify UMD with a plain function call. This ensures
77 +// that the internal wrapper doesn't interact with the external state. By the
78 +// time we're in the internal wrapper it doesn't matter what the external wrapper
79 +// detected. Browserify insulates its CommonJS system inside closures so can just
80 +// call that function and return it.
81 +// 2. We put our own UMD wrapper around that fixed internal function, ensuring
82 +// React is in scope. This outer wrapper is essentially the same UMD wrapper
83 +// browserify would create, just handling the scope issue.
84 +// Is this insane? Yes.
85 +// Does it work? Yes.
86 +// Should it go away ASAP? Yes.
87 function wrapperify(src) {
88 + var toReplace =
89 + `function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.${this.data.standalone} = f()}}`;
90 + if (src.indexOf(toReplace) === -1) {
91 + throw new Error('wrapperify failed to find code to replace');
92 + }
93 + src = src.replace(
94 + toReplace,
95 + `function(f){return f()}`
96 + );
97 return `
98 ;(function(f) {
99 // CommonJS
100 if (typeof exports === "object" && typeof module !== "undefined") {
82 - f(require('react'));
101 + module.exports = f(require('react'));
102
103 // RequireJS
104 } else if (typeof define === "function" && define.amd) {
86 - require(['react'], f);
105 + define(['react'], f);
106
107 // <script>
108 } else {
@@ -100,10 +119,10 @@ function wrapperify(src) {
119 // see https://github.com/facebook/react/issues/3037
120 g = this;
121 }
103 - f(g.React)
122 + g.${this.data.standalone} = f(g.React);
123 }
124 })(function(React) {
106 - ${src}
125 + return ${src}
126 });
127 `;
128 }