1111var _ = require ( 'underscore' ) ;
1212var base64VLQ = require ( './base64-vlq' ) ;
1313var UglifyJS = require ( 'uglify-js' ) ;
14+ var ModuleTransport = require ( '../lib/ModuleTransport' ) ;
1415
1516module . exports = Package ;
1617
@@ -19,22 +20,25 @@ function Package(sourceMapUrl) {
1920 this . _modules = [ ] ;
2021 this . _assets = [ ] ;
2122 this . _sourceMapUrl = sourceMapUrl ;
23+ this . _shouldCombineSourceMaps = false ;
2224}
2325
2426Package . prototype . setMainModuleId = function ( moduleId ) {
2527 this . _mainModuleId = moduleId ;
2628} ;
2729
28- Package . prototype . addModule = function (
29- transformedCode ,
30- sourceCode ,
31- sourcePath
32- ) {
33- this . _modules . push ( {
34- transformedCode : transformedCode ,
35- sourceCode : sourceCode ,
36- sourcePath : sourcePath
37- } ) ;
30+ Package . prototype . addModule = function ( module ) {
31+ if ( ! ( module instanceof ModuleTransport ) ) {
32+ throw new Error ( 'Expeceted a ModuleTransport object' ) ;
33+ }
34+
35+ // If we get a map from the transformer we'll switch to a mode
36+ // were we're combining the source maps as opposed to
37+ if ( ! this . _shouldCombineSourceMaps && module . map != null ) {
38+ this . _shouldCombineSourceMaps = true ;
39+ }
40+
41+ this . _modules . push ( module ) ;
3842} ;
3943
4044Package . prototype . addAsset = function ( asset ) {
@@ -45,11 +49,12 @@ Package.prototype.finalize = function(options) {
4549 options = options || { } ;
4650 if ( options . runMainModule ) {
4751 var runCode = ';require("' + this . _mainModuleId + '");' ;
48- this . addModule (
49- runCode ,
50- runCode ,
51- 'RunMainModule.js'
52- ) ;
52+ this . addModule ( new ModuleTransport ( {
53+ code : runCode ,
54+ virtual : true ,
55+ sourceCode : runCode ,
56+ sourcePath : 'RunMainModule.js'
57+ } ) ) ;
5358 }
5459
5560 Object . freeze ( this . _modules ) ;
@@ -67,7 +72,7 @@ Package.prototype._assertFinalized = function() {
6772
6873Package . prototype . _getSource = function ( ) {
6974 if ( this . _source == null ) {
70- this . _source = _ . pluck ( this . _modules , 'transformedCode ' ) . join ( '\n' ) ;
75+ this . _source = _ . pluck ( this . _modules , 'code ' ) . join ( '\n' ) ;
7176 }
7277 return this . _source ;
7378} ;
@@ -136,10 +141,50 @@ Package.prototype.getMinifiedSourceAndMap = function() {
136141 }
137142} ;
138143
144+ /**
145+ * I found a neat trick in the sourcemap spec that makes it easy
146+ * to concat sourcemaps. The `sections` field allows us to combine
147+ * the sourcemap easily by adding an offset. Tested on chrome.
148+ * Seems like it's not yet in Firefox but that should be fine for
149+ * now.
150+ */
151+ Package . prototype . _getCombinedSourceMaps = function ( options ) {
152+ var result = {
153+ version : 3 ,
154+ file : 'bundle.js' ,
155+ sections : [ ] ,
156+ } ;
157+
158+ var line = 0 ;
159+ this . _modules . forEach ( function ( module ) {
160+ var map = module . map ;
161+ if ( module . virtual ) {
162+ map = generateSourceMapForVirtualModule ( module ) ;
163+ }
164+
165+ if ( options . excludeSource ) {
166+ map = _ . extend ( { } , map , { sourcesContent : [ ] } ) ;
167+ }
168+
169+ result . sections . push ( {
170+ offset : { line : line , column : 0 } ,
171+ map : map ,
172+ } ) ;
173+ line += module . code . split ( '\n' ) . length ;
174+ } ) ;
175+
176+ return result ;
177+ } ;
178+
139179Package . prototype . getSourceMap = function ( options ) {
140180 this . _assertFinalized ( ) ;
141181
142182 options = options || { } ;
183+
184+ if ( this . _shouldCombineSourceMaps ) {
185+ return this . _getCombinedSourceMaps ( options ) ;
186+ }
187+
143188 var mappings = this . _getMappings ( ) ;
144189 var map = {
145190 file : 'bundle.js' ,
@@ -168,13 +213,14 @@ Package.prototype._getMappings = function() {
168213 // except for the lineno mappinp: curLineno - prevLineno = 1; Which is C.
169214 var line = 'AACA' ;
170215
216+ var moduleLines = Object . create ( null ) ;
171217 var mappings = '' ;
172218 for ( var i = 0 ; i < modules . length ; i ++ ) {
173219 var module = modules [ i ] ;
174- var transformedCode = module . transformedCode ;
220+ var code = module . code ;
175221 var lastCharNewLine = false ;
176- module . lines = 0 ;
177- for ( var t = 0 ; t < transformedCode . length ; t ++ ) {
222+ moduleLines [ module . sourcePath ] = 0 ;
223+ for ( var t = 0 ; t < code . length ; t ++ ) {
178224 if ( t === 0 && i === 0 ) {
179225 mappings += firstLine ;
180226 } else if ( t === 0 ) {
@@ -183,13 +229,15 @@ Package.prototype._getMappings = function() {
183229 // This is the only place were we actually don't know the mapping ahead
184230 // of time. When it's a new module (and not the first) the lineno
185231 // mapping is 0 (current) - number of lines in prev module.
186- mappings += base64VLQ . encode ( 0 - modules [ i - 1 ] . lines ) ;
232+ mappings += base64VLQ . encode (
233+ 0 - moduleLines [ modules [ i - 1 ] . sourcePath ]
234+ ) ;
187235 mappings += 'A' ;
188236 } else if ( lastCharNewLine ) {
189- module . lines ++ ;
237+ moduleLines [ module . sourcePath ] ++ ;
190238 mappings += line ;
191239 }
192- lastCharNewLine = transformedCode [ t ] === '\n' ;
240+ lastCharNewLine = code [ t ] === '\n' ;
193241 if ( lastCharNewLine ) {
194242 mappings += ';' ;
195243 }
@@ -218,7 +266,25 @@ Package.prototype.getDebugInfo = function() {
218266 this . _modules . map ( function ( m ) {
219267 return '<div> <h4> Path: </h4>' + m . sourcePath + '<br/> <h4> Source: </h4>' +
220268 '<code><pre class="collapsed" onclick="this.classList.remove(\'collapsed\')">' +
221- _ . escape ( m . transformedCode ) + '</pre></code></div>' ;
269+ _ . escape ( m . code ) + '</pre></code></div>' ;
222270 } ) . join ( '\n' ) ,
223271 ] . join ( '\n' ) ;
224272} ;
273+
274+ function generateSourceMapForVirtualModule ( module ) {
275+ // All lines map 1-to-1
276+ var mappings = 'AAAA;' ;
277+
278+ for ( var i = 1 ; i < module . code . split ( '\n' ) . length ; i ++ ) {
279+ mappings += 'AACA;' ;
280+ }
281+
282+ return {
283+ version : 3 ,
284+ sources : [ module . sourcePath ] ,
285+ names : [ ] ,
286+ mappings : mappings ,
287+ file : module . sourcePath ,
288+ sourcesContent : [ module . code ] ,
289+ } ;
290+ }
0 commit comments