@@ -185,11 +185,105 @@ function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap)
185185 } ) ;
186186
187187 return {
188- files : removeDuplicateTSBoilerplate ( result ) ,
188+ files : extractStrings ( removeDuplicateTSBoilerplate ( result ) ) ,
189189 bundleData : bundleData
190190 } ;
191191}
192192
193+ function extractStrings ( destFiles :IConcatFile [ ] ) :IConcatFile [ ] {
194+ let parseDefineCall = ( moduleMatch :string , depsMatch :string ) => {
195+ let module = moduleMatch . replace ( / ^ " | " $ / g, '' ) ;
196+ let deps = depsMatch . split ( ',' ) ;
197+ deps = deps . map ( ( dep ) => {
198+ dep = dep . trim ( ) ;
199+ dep = dep . replace ( / ^ " | " $ / g, '' ) ;
200+ dep = dep . replace ( / ^ ' | ' $ / g, '' ) ;
201+ let prefix :string = null ;
202+ let _path :string = null ;
203+ let pieces = dep . split ( '!' ) ;
204+ if ( pieces . length > 1 ) {
205+ prefix = pieces [ 0 ] + '!' ;
206+ _path = pieces [ 1 ] ;
207+ } else {
208+ prefix = '' ;
209+ _path = pieces [ 0 ] ;
210+ }
211+
212+ if ( / ^ \. \/ / . test ( _path ) || / ^ \. \. \/ / . test ( _path ) ) {
213+ let res = path . join ( path . dirname ( module ) , _path ) . replace ( / \\ / g, '/' ) ;
214+ return prefix + res ;
215+ }
216+ return prefix + _path ;
217+ } ) ;
218+ return {
219+ module : module ,
220+ deps : deps
221+ } ;
222+ } ;
223+
224+ destFiles . forEach ( ( destFile , index ) => {
225+ if ( ! / \. j s $ / . test ( destFile . dest ) ) {
226+ return ;
227+ }
228+ if ( / \. n l s \. j s $ / . test ( destFile . dest ) ) {
229+ return ;
230+ }
231+
232+ // Do one pass to record the usage counts for each module id
233+ let useCounts : { [ moduleId :string ] :number ; } = { } ;
234+ destFile . sources . forEach ( ( source ) => {
235+ let matches = source . contents . match ( / d e f i n e \( ( " [ ^ " ] + " ) , \s * \[ ( ( ( , ) ? ( " | ' ) [ ^ " ' ] + ( " | ' ) ) + ) \] / ) ;
236+ if ( ! matches ) {
237+ return ;
238+ }
239+
240+ let defineCall = parseDefineCall ( matches [ 1 ] , matches [ 2 ] ) ;
241+ useCounts [ defineCall . module ] = ( useCounts [ defineCall . module ] || 0 ) + 1 ;
242+ defineCall . deps . forEach ( ( dep ) => {
243+ useCounts [ dep ] = ( useCounts [ dep ] || 0 ) + 1 ;
244+ } ) ;
245+ } ) ;
246+
247+ let sortedByUseModules = Object . keys ( useCounts ) ;
248+ sortedByUseModules . sort ( ( a , b ) => {
249+ return useCounts [ b ] - useCounts [ a ] ;
250+ } ) ;
251+
252+ let replacementMap : { [ moduleId :string ] :number ; } = { } ;
253+ sortedByUseModules . forEach ( ( module , index ) => {
254+ replacementMap [ module ] = index ;
255+ } ) ;
256+
257+ destFile . sources . forEach ( ( source ) => {
258+ source . contents = source . contents . replace ( / d e f i n e \( ( " [ ^ " ] + " ) , \s * \[ ( ( ( , ) ? ( " | ' ) [ ^ " ' ] + ( " | ' ) ) + ) \] / , ( _ , moduleMatch , depsMatch ) => {
259+ let defineCall = parseDefineCall ( moduleMatch , depsMatch ) ;
260+ return `define(__m[${ replacementMap [ defineCall . module ] } ], __M([${ defineCall . deps . map ( dep => replacementMap [ dep ] ) . join ( ',' ) } ])` ;
261+ } ) ;
262+ } ) ;
263+
264+ destFile . sources . unshift ( {
265+ path : null ,
266+ contents : [
267+ '(function() {' ,
268+ `var __m = ${ JSON . stringify ( sortedByUseModules ) } ;` ,
269+ `var __M = function(deps) {` ,
270+ ` var result = [];` ,
271+ ` for (var i = 0, len = deps.length; i < len; i++) {` ,
272+ ` result[i] = __m[deps[i]];` ,
273+ ` }` ,
274+ ` return result;` ,
275+ `};`
276+ ] . join ( '\n' )
277+ } ) ;
278+
279+ destFile . sources . push ( {
280+ path : null ,
281+ contents : '}).call(this);'
282+ } ) ;
283+ } ) ;
284+ return destFiles ;
285+ }
286+
193287function removeDuplicateTSBoilerplate ( destFiles :IConcatFile [ ] ) :IConcatFile [ ] {
194288 // Taken from typescript compiler => emitFiles
195289 let BOILERPLATE = [
0 commit comments