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' ) ;
13
15
14
16
/**
15
17
* 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');
18
20
* @returns {boolean } True on valid node and valid match, else false
19
21
*/
20
22
function isLiteralAST ( node ) {
21
- 'use strict' ;
22
23
var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
23
24
return ( node ) && ( node . type === 'Literal' ) && candidates . some ( function ( candidate ) {
24
25
return ( node . value === candidate )
@@ -33,7 +34,6 @@ function isLiteralAST(node) {
33
34
* @returns {boolean } True on valid node and valid match, else false
34
35
*/
35
36
function isMethodAST ( node ) {
36
- 'use strict' ;
37
37
var candidates = Array . prototype . slice . call ( arguments , 1 ) ;
38
38
var result = ( node ) && ( node . type === 'CallExpression' ) && ( node . callee ) && candidates . some ( function ( candidate ) {
39
39
var callee = node . callee ;
@@ -49,7 +49,6 @@ function isMethodAST(node) {
49
49
* @return A jasmine transform
50
50
*/
51
51
function jasmineTransform ( symbol ) {
52
- 'use strict' ;
53
52
return transformTools . makeFalafelTransform ( 'jasmineTransform' , null , function ( node , options , done ) {
54
53
var isValid = isLiteralAST ( node , symbol ) && isMethodAST ( node . parent , 'describe' , 'module' ) ;
55
54
if ( isValid ) {
@@ -67,7 +66,6 @@ function jasmineTransform(symbol) {
67
66
* @returns {stream.Through } A through stream that performs the operation of a gulp stream
68
67
*/
69
68
function compile ( bannerWidth , transforms ) {
70
- 'use strict' ;
71
69
var output = [ ] ;
72
70
73
71
/**
@@ -87,39 +85,48 @@ function compile(bannerWidth, transforms) {
87
85
* Mapping function that injects new-line return between dissimilar messages
88
86
*/
89
87
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 ] ;
92
90
var isDissimilar = ( i > 0 ) && ( i < array . length ) && ( current !== previous ) ;
93
- var result = isDissimilar ? ( '\n' + value ) : value ;
91
+ var result = isDissimilar ? ( '\n' + value ) : value ;
94
92
return result ;
95
93
}
96
94
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
-
109
95
/**
110
96
* Compile any number of files into a bundle
111
97
* @param {stream.Through } stream A stream to push files to
112
98
* @param {Array.<string>|string } files Any number of files to bundle
113
99
* @param {string } bundlename The name for the output file
114
100
* @param {function|boolean } [minify] Determines whether minification is performed
101
+ * @param {string } [sourceMapBase] Base path for source map file
115
102
* @param {function } done Callback for completion
116
103
*/
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
+ }
118
126
119
127
// Simulate bower components (and optionally current project) as node modules that may be require()'d
120
128
var anonymised = trackFilenames ( ) . create ( ) ;
121
129
function requireTransform ( allowProjectRelative ) {
122
- 'use strict' ;
123
130
var BOWER = path . relative ( process . cwd ( ) , bowerDir . sync ( ) ) ;
124
131
return transformTools . makeRequireTransform ( 'requireTransform' , null , function ( args , opts , done ) {
125
132
@@ -160,12 +167,11 @@ function compile(bannerWidth, transforms) {
160
167
}
161
168
162
169
// 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' ;
166
172
var isMinify = ( minify ) && ( ( typeof minify !== 'function' ) || minify ( bundlename ) ) ;
167
- var count = 0 ;
168
- var bundler = browserify ( {
173
+ var count = 0 ;
174
+ var bundler = browserify ( {
169
175
debug : true
170
176
} ) ;
171
177
@@ -224,7 +230,8 @@ function compile(bannerWidth, transforms) {
224
230
// stream output
225
231
function pushFileToStream ( path , text ) {
226
232
stream . push ( new gutil . File ( {
227
- cwd : cwd , base : cwd , path : path , contents : new Buffer ( text )
233
+ path : path ,
234
+ contents : new Buffer ( text )
228
235
} ) ) ;
229
236
}
230
237
@@ -244,48 +251,40 @@ function compile(bannerWidth, transforms) {
244
251
bundler . require ( item , { entry : true } ) ;
245
252
} ) ;
246
253
247
- // minify requires callback style
254
+ // configure minification
248
255
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
254
260
sequences : false ,
255
261
join_vars : false
256
- } , mangle : {
262
+ } ,
263
+ mangle : {
257
264
toplevel : true
258
265
}
259
266
}
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
+ } ) ;
288
268
}
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 ) ;
289
288
}
290
289
291
290
// return a set of streams
@@ -294,11 +293,12 @@ function compile(bannerWidth, transforms) {
294
293
/**
295
294
* A stream that produces a bundle for each file in the stream
296
295
* @param {function|boolean } [isMinify] Determines whether minification is performed
296
+ * @param {string } [sourceMapBase] Base path for source map file
297
297
* @returns {stream.Through }
298
298
*/
299
- each : function ( isMinify ) {
299
+ each : function ( isMinify , sourceMapBase ) {
300
300
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 ) ;
302
302
} , function ( done ) {
303
303
flushErrors ( ) ;
304
304
done ( ) ;
@@ -309,16 +309,17 @@ function compile(bannerWidth, transforms) {
309
309
* A stream that produces a bundle containing all files in the stream
310
310
* @param {string } outPath A relative path for the output file
311
311
* @param {function|boolean } [isMinify] Determines whether minification is performed
312
+ * @param {string } [sourceMapBase] Base path for source map file
312
313
* @returns {stream.Through }
313
314
*/
314
- all : function ( outPath , isMinify ) {
315
+ all : function ( outPath , isMinify , sourceMapBase ) {
315
316
var pending = [ ] ;
316
317
return through . obj ( function ( file , encoding , done ) {
317
318
pending . push ( file . path ) ;
318
319
done ( ) ;
319
320
} , function ( done ) {
320
321
if ( pending . length ) {
321
- bundle ( this , pending , outPath , isMinify , function ( ) {
322
+ bundle ( this , pending , outPath , isMinify , sourceMapBase , function ( ) {
322
323
flushErrors ( ) ;
323
324
done ( ) ;
324
325
} ) ;
@@ -332,5 +333,5 @@ function compile(bannerWidth, transforms) {
332
333
333
334
module . exports = {
334
335
jasmineTransform : jasmineTransform ,
335
- compile : compile
336
+ compile : compile
336
337
} ;
0 commit comments