1- var fs = require ( 'fs' ) ;
2- var path = require ( 'path' ) ;
3- var through = require ( 'through2' ) ;
4- var trackFilenames = require ( 'gulp-track-filenames' ) ;
5- var transformTools = require ( 'browserify-transform-tools' ) ;
6- var browserify = require ( 'browserify' ) ;
7- var gutil = require ( 'gulp-util' ) ;
8- var minifyify = require ( 'minifyify' ) ;
9- var moldSourceMap = require ( 'mold-source-map' ) ;
10- var slash = require ( 'gulp-slash' ) ;
11- 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' ) ;
1215
1316/**
1417 * Test a given esprima AST node as a literal with one of the possible given values
@@ -17,7 +20,6 @@ var bowerDir = require('bower-directory');
1720 * @returns {boolean } True on valid node and valid match, else false
1821 */
1922function isLiteralAST ( node ) {
20- 'use strict' ;
2123 var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
2224 return ( node ) && ( node . type === 'Literal' ) && candidates . some ( function ( candidate ) {
2325 return ( node . value === candidate )
@@ -32,7 +34,6 @@ function isLiteralAST(node) {
3234 * @returns {boolean } True on valid node and valid match, else false
3335 */
3436function isMethodAST ( node ) {
35- 'use strict' ;
3637 var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
3738 var result = ( node ) && ( node . type === 'CallExpression' ) && ( node . callee ) && candidates . some ( function ( candidate ) {
3839 var callee = node . callee ;
@@ -48,7 +49,6 @@ function isMethodAST(node) {
4849 * @return A jasmine transform
4950 */
5051function jasmineTransform ( symbol ) {
51- 'use strict' ;
5252 return transformTools . makeFalafelTransform ( 'jasmineTransform' , null , function ( node , options , done ) {
5353 var isValid = isLiteralAST ( node , symbol ) && isMethodAST ( node . parent , 'describe' , 'module' ) ;
5454 if ( isValid ) {
@@ -66,7 +66,6 @@ function jasmineTransform(symbol) {
6666 * @returns {stream.Through } A through stream that performs the operation of a gulp stream
6767 */
6868function compile ( bannerWidth , transforms ) {
69- 'use strict' ;
7069 var output = [ ] ;
7170
7271 /**
@@ -86,39 +85,48 @@ function compile(bannerWidth, transforms) {
8685 * Mapping function that injects new-line return between dissimilar messages
8786 */
8887 function groupByFilename ( value , i , array ) {
89- var current = String ( value ) . split ( / \: \d + / ) [ 0 ] ;
90- 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 ] ;
9190 var isDissimilar = ( i > 0 ) && ( i < array . length ) && ( current !== previous ) ;
92- var result = isDissimilar ? ( '\n' + value ) : value ;
91+ var result = isDissimilar ? ( '\n' + value ) : value ;
9392 return result ;
9493 }
9594
96- /**
97- * Determine the root relative form of the given file path.
98- * If the file path is outside the project directory then just return its name.
99- * @param {string } filePath Full file path
100- * @returns {string } Give path relative to process.cwd()
101- */
102- function rootRelative ( filePath ) {
103- var rootRelative = slash ( path . relative ( process . cwd ( ) , filePath ) ) ;
104- var isProject = ( rootRelative . slice ( 0 , 2 ) !== '..' ) ;
105- return '/' + ( isProject ? rootRelative : path . basename ( rootRelative ) ) ;
106- }
107-
10895 /**
10996 * Compile any number of files into a bundle
11097 * @param {stream.Through } stream A stream to push files to
11198 * @param {Array.<string>|string } files Any number of files to bundle
11299 * @param {string } bundlename The name for the output file
113100 * @param {function|boolean } [minify] Determines whether minification is performed
101+ * @param {string } [sourceMapBase] Base path for source map file
114102 * @param {function } done Callback for completion
115103 */
116- 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+ }
117126
118127 // Simulate bower components (and optionally current project) as node modules that may be require()'d
119128 var anonymised = trackFilenames ( ) . create ( ) ;
120129 function requireTransform ( allowProjectRelative ) {
121- 'use strict' ;
122130 var BOWER = path . relative ( process . cwd ( ) , bowerDir . sync ( ) ) ;
123131 return transformTools . makeRequireTransform ( 'requireTransform' , null , function ( args , opts , done ) {
124132
@@ -159,12 +167,11 @@ function compile(bannerWidth, transforms) {
159167 }
160168
161169 // setup
162- var cwd = process . cwd ( ) ;
163- var outPath = path . join ( cwd , bundlename ) ;
164- var mapPath = path . basename ( bundlename ) + '.map' ;
170+ var outPath = path . resolve ( bundlename ) ;
171+ var mapPath = path . basename ( bundlename ) + '.map' ;
165172 var isMinify = ( minify ) && ( ( typeof minify !== 'function' ) || minify ( bundlename ) ) ;
166- var count = 0 ;
167- var bundler = browserify ( {
173+ var count = 0 ;
174+ var bundler = browserify ( {
168175 debug : true
169176 } ) ;
170177
@@ -223,17 +230,19 @@ function compile(bannerWidth, transforms) {
223230 // stream output
224231 function pushFileToStream ( path , text ) {
225232 stream . push ( new gutil . File ( {
226- cwd : cwd , base : cwd , path : path , contents : new Buffer ( text )
233+ path : path ,
234+ contents : new Buffer ( text )
227235 } ) ) ;
228236 }
229237
230238 // transforms
231239 transforms
232240 . concat ( requireTransform ( false ) )
233- . filter ( function ( candidate ) {
234- return ( typeof candidate === 'function' ) ;
235- } ) . forEach ( function ( item ) {
236- bundler . transform ( item , { global : true } ) ;
241+ . forEach ( function ( item , i , list ) {
242+ if ( typeof item === 'function' ) {
243+ var opts = ( typeof list [ i + 1 ] === 'object' ) ? merge ( { global : true } , list [ i + 1 ] ) : { global : true } ;
244+ bundler . transform ( item , opts ) ;
245+ }
237246 } ) ;
238247
239248 // require statements
@@ -242,48 +251,40 @@ function compile(bannerWidth, transforms) {
242251 bundler . require ( item , { entry : true } ) ;
243252 } ) ;
244253
245- // minify requires callback style
254+ // configure minification
246255 if ( isMinify ) {
247- var minifyOptions = {
248- map : mapPath ,
249- compressPath : rootRelative ,
250- uglify : {
251- 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
252260 sequences : false ,
253261 join_vars : false
254- } , mangle : {
262+ } ,
263+ mangle : {
255264 toplevel : true
256265 }
257266 }
258- } ;
259- minifyify ( bundler , minifyOptions ) ;
260- bundler . bundle ( function ( error , code , map ) {
261- if ( ! error ) {
262- var sourcemap = JSON . parse ( map ) ;
263- delete sourcemap . file ;
264- delete sourcemap . sourcesContent ;
265- pushFileToStream ( outPath + '.map' , JSON . stringify ( sourcemap , null , 2 ) ) ;
266- pushFileToStream ( outPath , anonymised . replace ( code , '"' , '"' ) ) ; // anonymise module paths
267- }
268- done ( ) ; // complete overall
269- } ) . on ( 'error' , errorHandler ) ;
270-
271- // non-minify requires stream style
272- } else {
273- bundler . bundle ( )
274- . on ( 'error' , errorHandler )
275- . pipe ( moldSourceMap . transform ( function ( molder , complete ) {
276- molder . mapSources ( rootRelative ) ;
277- molder . sourcemap . setProperty ( 'file' ) ;
278- molder . sourcemap . setProperty ( 'sourcesContent' ) ;
279- molder . sourcemap . setProperty ( 'sourceRoot' ) ;
280- pushFileToStream ( outPath + '.map' , molder . sourcemap . toJSON ( 2 ) ) ;
281- complete ( '//# sourceMappingURL=' + mapPath ) ;
282- } ) ) . on ( 'data' , function ( contents ) {
283- pushFileToStream ( outPath , contents ) ;
284- done ( ) ; // complete overall
285- } ) ;
267+ } ) ;
286268 }
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 ) ;
287288 }
288289
289290 // return a set of streams
@@ -292,11 +293,12 @@ function compile(bannerWidth, transforms) {
292293 /**
293294 * A stream that produces a bundle for each file in the stream
294295 * @param {function|boolean } [isMinify] Determines whether minification is performed
296+ * @param {string } [sourceMapBase] Base path for source map file
295297 * @returns {stream.Through }
296298 */
297- each : function ( isMinify ) {
299+ each : function ( isMinify , sourceMapBase ) {
298300 return through . obj ( function ( file , encoding , done ) {
299- bundle ( this , [ file . path ] , file . relative , isMinify , done ) ;
301+ bundle ( this , [ file . path ] , file . relative , isMinify , sourceMapBase , done ) ;
300302 } , function ( done ) {
301303 flushErrors ( ) ;
302304 done ( ) ;
@@ -307,16 +309,17 @@ function compile(bannerWidth, transforms) {
307309 * A stream that produces a bundle containing all files in the stream
308310 * @param {string } outPath A relative path for the output file
309311 * @param {function|boolean } [isMinify] Determines whether minification is performed
312+ * @param {string } [sourceMapBase] Base path for source map file
310313 * @returns {stream.Through }
311314 */
312- all : function ( outPath , isMinify ) {
315+ all : function ( outPath , isMinify , sourceMapBase ) {
313316 var pending = [ ] ;
314317 return through . obj ( function ( file , encoding , done ) {
315318 pending . push ( file . path ) ;
316319 done ( ) ;
317320 } , function ( done ) {
318321 if ( pending . length ) {
319- bundle ( this , pending , outPath , isMinify , function ( ) {
322+ bundle ( this , pending , outPath , isMinify , sourceMapBase , function ( ) {
320323 flushErrors ( ) ;
321324 done ( ) ;
322325 } ) ;
@@ -330,5 +333,5 @@ function compile(bannerWidth, transforms) {
330333
331334module . exports = {
332335 jasmineTransform : jasmineTransform ,
333- compile : compile
336+ compile : compile
334337} ;
0 commit comments