1- var fs = require ( 'fs' ) ;
2- var path = require ( 'path' ) ;
3- var through = require ( 'through2' ) ;
4- var merge = require ( 'lodash.merge' ) ;
5- var trackFilenames = require ( 'gulp-track-filenames' ) ;
6- var transformTools = require ( 'browserify-transform-tools' ) ;
7- var browserify = require ( 'browserify' ) ;
8- var gutil = require ( 'gulp-util' ) ;
9- var minifyify = require ( 'minifyify' ) ;
10- var moldSourceMap = require ( 'mold-source-map' ) ;
11- var slash = require ( 'gulp-slash' ) ;
12- var bowerDir = require ( 'bower-directory' ) ;
1+ 'use strict' ;
2+
3+ var fs = require ( 'fs' ) ,
4+ path = require ( 'path' ) ,
5+ through = require ( 'through2' ) ,
6+ merge = require ( 'lodash.merge' ) ,
7+ trackFilenames = require ( 'gulp-track-filenames' ) ,
8+ transformTools = require ( 'browserify-transform-tools' ) ,
9+ browserify = require ( 'browserify' ) ,
10+ convert = require ( 'convert-source-map' ) ,
11+ gutil = require ( 'gulp-util' ) ,
12+ minifyify = require ( 'minifyify' ) ,
13+ slash = require ( 'gulp-slash' ) ,
14+ bowerDir = require ( 'bower-directory' ) ;
1315
1416/**
1517 * Test a given esprima AST node as a literal with one of the possible given values
@@ -18,7 +20,6 @@ var bowerDir = require('bower-directory');
1820 * @returns {boolean } True on valid node and valid match, else false
1921 */
2022function isLiteralAST ( node ) {
21- 'use strict' ;
2223 var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
2324 return ( node ) && ( node . type === 'Literal' ) && candidates . some ( function ( candidate ) {
2425 return ( node . value === candidate )
@@ -33,7 +34,6 @@ function isLiteralAST(node) {
3334 * @returns {boolean } True on valid node and valid match, else false
3435 */
3536function isMethodAST ( node ) {
36- 'use strict' ;
3737 var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
3838 var result = ( node ) && ( node . type === 'CallExpression' ) && ( node . callee ) && candidates . some ( function ( candidate ) {
3939 var callee = node . callee ;
@@ -49,7 +49,6 @@ function isMethodAST(node) {
4949 * @return A jasmine transform
5050 */
5151function jasmineTransform ( symbol ) {
52- 'use strict' ;
5352 return transformTools . makeFalafelTransform ( 'jasmineTransform' , null , function ( node , options , done ) {
5453 var isValid = isLiteralAST ( node , symbol ) && isMethodAST ( node . parent , 'describe' , 'module' ) ;
5554 if ( isValid ) {
@@ -67,7 +66,6 @@ function jasmineTransform(symbol) {
6766 * @returns {stream.Through } A through stream that performs the operation of a gulp stream
6867 */
6968function compile ( bannerWidth , transforms ) {
70- 'use strict' ;
7169 var output = [ ] ;
7270
7371 /**
@@ -87,39 +85,48 @@ function compile(bannerWidth, transforms) {
8785 * Mapping function that injects new-line return between dissimilar messages
8886 */
8987 function groupByFilename ( value , i , array ) {
90- var current = String ( value ) . split ( / \: \d + / ) [ 0 ] ;
91- var previous = String ( array [ i - 1 ] ) . split ( / \: \d + / ) [ 0 ] ;
88+ var current = String ( value ) . split ( / \: \d + / ) [ 0 ] ;
89+ var previous = String ( array [ i - 1 ] ) . split ( / \: \d + / ) [ 0 ] ;
9290 var isDissimilar = ( i > 0 ) && ( i < array . length ) && ( current !== previous ) ;
93- var result = isDissimilar ? ( '\n' + value ) : value ;
91+ var result = isDissimilar ? ( '\n' + value ) : value ;
9492 return result ;
9593 }
9694
97- /**
98- * Determine the root relative form of the given file path.
99- * If the file path is outside the project directory then just return its name.
100- * @param {string } filePath Full file path
101- * @returns {string } Give path relative to process.cwd()
102- */
103- function rootRelative ( filePath ) {
104- var rootRelative = slash ( path . relative ( process . cwd ( ) , filePath ) ) ;
105- var isProject = ( rootRelative . slice ( 0 , 2 ) !== '..' ) ;
106- return '/' + ( isProject ? rootRelative : path . basename ( rootRelative ) ) ;
107- }
108-
10995 /**
11096 * Compile any number of files into a bundle
11197 * @param {stream.Through } stream A stream to push files to
11298 * @param {Array.<string>|string } files Any number of files to bundle
11399 * @param {string } bundlename The name for the output file
114100 * @param {function|boolean } [minify] Determines whether minification is performed
101+ * @param {string } [sourceMapBase] Base path for source map file
115102 * @param {function } done Callback for completion
116103 */
117- function bundle ( stream , files , bundlename , minify , done ) {
104+ function bundle ( stream , files , bundlename , minify , sourceMapBase , done ) {
105+
106+ /**
107+ * Determine the root relative form of the given file path.
108+ * If the file path is outside the project directory then just return its name.
109+ * @param {string } filePath The input path string
110+ * @param {number } An index for <code>Array.map()</code> type operations
111+ * @param {object } The array for <code>Array.map()</code> type operations
112+ * @return {string } The transformed file path
113+ */
114+ function rootRelative ( filePath , i , array ) {
115+ var rootRelative = slash ( path . relative ( process . cwd ( ) , path . resolve ( filePath ) ) ) ; // resolve relative references
116+ var isProject = ( rootRelative . slice ( 0 , 2 ) !== '..' ) ;
117+ var result = [
118+ sourceMapBase || '' ,
119+ isProject ? rootRelative : path . basename ( rootRelative )
120+ ] . join ( path . sep ) ;
121+ if ( ( typeof i === 'number' ) && ( typeof array === 'object' ) ) {
122+ array [ i ] = result ;
123+ }
124+ return result ;
125+ }
118126
119127 // Simulate bower components (and optionally current project) as node modules that may be require()'d
120128 var anonymised = trackFilenames ( ) . create ( ) ;
121129 function requireTransform ( allowProjectRelative ) {
122- 'use strict' ;
123130 var BOWER = path . relative ( process . cwd ( ) , bowerDir . sync ( ) ) ;
124131 return transformTools . makeRequireTransform ( 'requireTransform' , null , function ( args , opts , done ) {
125132
@@ -160,12 +167,11 @@ function compile(bannerWidth, transforms) {
160167 }
161168
162169 // setup
163- var cwd = process . cwd ( ) ;
164- var outPath = path . join ( cwd , bundlename ) ;
165- var mapPath = path . basename ( bundlename ) + '.map' ;
170+ var outPath = path . resolve ( bundlename ) ;
171+ var mapPath = path . basename ( bundlename ) + '.map' ;
166172 var isMinify = ( minify ) && ( ( typeof minify !== 'function' ) || minify ( bundlename ) ) ;
167- var count = 0 ;
168- var bundler = browserify ( {
173+ var count = 0 ;
174+ var bundler = browserify ( {
169175 debug : true
170176 } ) ;
171177
@@ -224,7 +230,8 @@ function compile(bannerWidth, transforms) {
224230 // stream output
225231 function pushFileToStream ( path , text ) {
226232 stream . push ( new gutil . File ( {
227- cwd : cwd , base : cwd , path : path , contents : new Buffer ( text )
233+ path : path ,
234+ contents : new Buffer ( text )
228235 } ) ) ;
229236 }
230237
@@ -244,48 +251,40 @@ function compile(bannerWidth, transforms) {
244251 bundler . require ( item , { entry : true } ) ;
245252 } ) ;
246253
247- // minify requires callback style
254+ // configure minification
248255 if ( isMinify ) {
249- var minifyOptions = {
250- map : mapPath ,
251- compressPath : rootRelative ,
252- uglify : {
253- compress : { // anything that changes semicolons to commas will cause debugger problems
256+ minifyify ( bundler , {
257+ map : mapPath ,
258+ uglify : {
259+ compress : { // anything that changes semicolons to commas will cause debugger problems
254260 sequences : false ,
255261 join_vars : false
256- } , mangle : {
262+ } ,
263+ mangle : {
257264 toplevel : true
258265 }
259266 }
260- } ;
261- minifyify ( bundler , minifyOptions ) ;
262- bundler . bundle ( function ( error , code , map ) {
263- if ( ! error ) {
264- var sourcemap = JSON . parse ( map ) ;
265- delete sourcemap . file ;
266- delete sourcemap . sourcesContent ;
267- pushFileToStream ( outPath + '.map' , JSON . stringify ( sourcemap , null , 2 ) ) ;
268- pushFileToStream ( outPath , anonymised . replace ( code , '"' , '"' ) ) ; // anonymise module paths
269- }
270- done ( ) ; // complete overall
271- } ) . on ( 'error' , errorHandler ) ;
272-
273- // non-minify requires stream style
274- } else {
275- bundler . bundle ( )
276- . on ( 'error' , errorHandler )
277- . pipe ( moldSourceMap . transform ( function ( molder , complete ) {
278- molder . mapSources ( rootRelative ) ;
279- molder . sourcemap . setProperty ( 'file' ) ;
280- molder . sourcemap . setProperty ( 'sourcesContent' ) ;
281- molder . sourcemap . setProperty ( 'sourceRoot' ) ;
282- pushFileToStream ( outPath + '.map' , molder . sourcemap . toJSON ( 2 ) ) ;
283- complete ( '//# sourceMappingURL=' + mapPath ) ;
284- } ) ) . on ( 'data' , function ( contents ) {
285- pushFileToStream ( outPath , contents ) ;
286- done ( ) ; // complete overall
287- } ) ;
267+ } ) ;
288268 }
269+
270+ // when we use minification we will get: error, code, source-map
271+ // when we don't we will get: error, buffer(with embedded source map)
272+ bundler . bundle ( function ( error , codeOrBuffer , map ) {
273+ if ( ! error ) {
274+ var code = codeOrBuffer . toString ( ) ;
275+ var sourceMap = map ? JSON . parse ( map ) : convert . fromComment ( code ) . toObject ( ) ;
276+ var external = map ? code : code . replace ( convert . commentRegex , '//# sourceMappingURL=' + mapPath ) ;
277+ var anonymous = isMinify ? anonymised . replace ( external , '"' , '"' ) : external ; // anonymise module paths
278+ delete sourceMap . file ;
279+ delete sourceMap . sourcesContent ;
280+ sourceMap . sources
281+ . forEach ( rootRelative ) ;
282+ pushFileToStream ( outPath + '.map' , JSON . stringify ( sourceMap , null , 2 ) ) ;
283+ pushFileToStream ( outPath , anonymous ) ;
284+ }
285+ done ( ) ; // complete overall
286+ } )
287+ . on ( 'error' , errorHandler ) ;
289288 }
290289
291290 // return a set of streams
@@ -294,11 +293,12 @@ function compile(bannerWidth, transforms) {
294293 /**
295294 * A stream that produces a bundle for each file in the stream
296295 * @param {function|boolean } [isMinify] Determines whether minification is performed
296+ * @param {string } [sourceMapBase] Base path for source map file
297297 * @returns {stream.Through }
298298 */
299- each : function ( isMinify ) {
299+ each : function ( isMinify , sourceMapBase ) {
300300 return through . obj ( function ( file , encoding , done ) {
301- bundle ( this , [ file . path ] , file . relative , isMinify , done ) ;
301+ bundle ( this , [ file . path ] , file . relative , isMinify , sourceMapBase , done ) ;
302302 } , function ( done ) {
303303 flushErrors ( ) ;
304304 done ( ) ;
@@ -309,16 +309,17 @@ function compile(bannerWidth, transforms) {
309309 * A stream that produces a bundle containing all files in the stream
310310 * @param {string } outPath A relative path for the output file
311311 * @param {function|boolean } [isMinify] Determines whether minification is performed
312+ * @param {string } [sourceMapBase] Base path for source map file
312313 * @returns {stream.Through }
313314 */
314- all : function ( outPath , isMinify ) {
315+ all : function ( outPath , isMinify , sourceMapBase ) {
315316 var pending = [ ] ;
316317 return through . obj ( function ( file , encoding , done ) {
317318 pending . push ( file . path ) ;
318319 done ( ) ;
319320 } , function ( done ) {
320321 if ( pending . length ) {
321- bundle ( this , pending , outPath , isMinify , function ( ) {
322+ bundle ( this , pending , outPath , isMinify , sourceMapBase , function ( ) {
322323 flushErrors ( ) ;
323324 done ( ) ;
324325 } ) ;
@@ -332,5 +333,5 @@ function compile(bannerWidth, transforms) {
332333
333334module . exports = {
334335 jasmineTransform : jasmineTransform ,
335- compile : compile
336+ compile : compile
336337} ;
0 commit comments