@@ -103,6 +103,13 @@ define(function (require) {
103
103
return dirName ;
104
104
}
105
105
106
+ function endsWithNewLine ( text ) {
107
+ if ( text . charAt ( text . length - 1 ) !== "\n" ) {
108
+ text += "\n" ;
109
+ }
110
+ return text ;
111
+ }
112
+
106
113
//Method used by plugin writeFile calls, defined up here to avoid
107
114
//jslint warning about "making a function in a loop".
108
115
function makeWriteFile ( namespace , layer ) {
@@ -119,6 +126,75 @@ define(function (require) {
119
126
return writeFile ;
120
127
}
121
128
129
+ /**
130
+ * Appends singleContents to fileContents and returns the result. If a sourceMapGenerator
131
+ * is provided, adds singleContents to the source map.
132
+ *
133
+ * @param {string } fileContents - The file contents to which to append singleContents
134
+ * @param {string } singleContents - The additional contents to append to fileContents
135
+ * @param {string } path - An absolute path of a file whose name to use in the source map.
136
+ * The file need not actually exist if the code in singleContents is generated.
137
+ * @param {{out: ?string, baseUrl: ?string} } config - The build configuration object.
138
+ * @param {?{_buildPath: ?string} } module - An object with module information.
139
+ * @param {?SourceMapGenerator } sourceMapGenerator - An instance of Mozilla's SourceMapGenerator,
140
+ * or null if no source map is being generated.
141
+ * @returns {string } fileContents with singleContents appended
142
+ */
143
+ function appendToFileContents ( fileContents , singleContents , path , config , module , sourceMapGenerator ) {
144
+ var refPath , sourceMapPath , resourcePath , pluginId , sourceMapLineNumber , lineCount , parts , i ;
145
+ if ( sourceMapGenerator ) {
146
+ if ( config . out ) {
147
+ refPath = config . baseUrl ;
148
+ } else if ( module && module . _buildPath ) {
149
+ refPath = module . _buildPath ;
150
+ } else {
151
+ refPath = "" ;
152
+ }
153
+ parts = path . split ( '!' ) ;
154
+ if ( parts . length === 1 ) {
155
+ //Not a plugin resource, fix the path
156
+ sourceMapPath = build . makeRelativeFilePath ( refPath , path ) ;
157
+ } else {
158
+ //Plugin resource. If it looks like just a plugin
159
+ //followed by a module ID, pull off the plugin
160
+ //and put it at the end of the name, otherwise
161
+ //just leave it alone.
162
+ pluginId = parts . shift ( ) ;
163
+ resourcePath = parts . join ( '!' ) ;
164
+ if ( resourceIsModuleIdRegExp . test ( resourcePath ) ) {
165
+ sourceMapPath = build . makeRelativeFilePath ( refPath , require . toUrl ( resourcePath ) ) +
166
+ '!' + pluginId ;
167
+ } else {
168
+ sourceMapPath = path ;
169
+ }
170
+ }
171
+
172
+ sourceMapLineNumber = fileContents . split ( '\n' ) . length - 1 ;
173
+ lineCount = singleContents . split ( '\n' ) . length ;
174
+ for ( i = 1 ; i <= lineCount ; i += 1 ) {
175
+ sourceMapGenerator . addMapping ( {
176
+ generated : {
177
+ line : sourceMapLineNumber + i ,
178
+ column : 0
179
+ } ,
180
+ original : {
181
+ line : i ,
182
+ column : 0
183
+ } ,
184
+ source : sourceMapPath
185
+ } ) ;
186
+ }
187
+
188
+ //Store the content of the original in the source
189
+ //map since other transforms later like minification
190
+ //can mess up translating back to the original
191
+ //source.
192
+ sourceMapGenerator . setSourceContent ( sourceMapPath , singleContents ) ;
193
+ }
194
+ fileContents += singleContents ;
195
+ return fileContents ;
196
+ }
197
+
122
198
/**
123
199
* Main API entry point into the build. The args argument can either be
124
200
* an array of arguments (like the onese passed on a command-line),
@@ -989,22 +1065,37 @@ define(function (require) {
989
1065
* Converts a wrap.startFile or endFile to be start/end as a string.
990
1066
* the startFile/endFile values can be arrays.
991
1067
*/
992
- function flattenWrapFile ( wrap , keyName , absFilePath ) {
993
- var keyFileName = keyName + 'File' ;
1068
+ function flattenWrapFile ( config , keyName , absFilePath ) {
1069
+ var wrap = config . wrap ,
1070
+ keyFileName = keyName + 'File' ,
1071
+ keyMapName = '__' + keyName + 'Map' ;
994
1072
995
1073
if ( typeof wrap [ keyName ] !== 'string' && wrap [ keyFileName ] ) {
996
1074
wrap [ keyName ] = '' ;
997
1075
if ( typeof wrap [ keyFileName ] === 'string' ) {
998
1076
wrap [ keyFileName ] = [ wrap [ keyFileName ] ] ;
999
1077
}
1078
+ wrap [ keyMapName ] = [ ] ;
1000
1079
wrap [ keyFileName ] . forEach ( function ( fileName ) {
1001
- wrap [ keyName ] += ( wrap [ keyName ] ? '\n' : '' ) +
1002
- file . readFile ( build . makeAbsPath ( fileName , absFilePath ) ) ;
1080
+ var absPath = build . makeAbsPath ( fileName , absFilePath ) ,
1081
+ fileText = endsWithNewLine ( file . readFile ( absPath ) ) ;
1082
+ wrap [ keyMapName ] . push ( function ( fileContents , cfg , sourceMapGenerator ) {
1083
+ return appendToFileContents ( fileContents , fileText , absPath , cfg , null , sourceMapGenerator ) ;
1084
+ } ) ;
1085
+ wrap [ keyName ] += fileText ;
1003
1086
} ) ;
1004
1087
} else if ( wrap [ keyName ] === null || wrap [ keyName ] === undefined ) {
1005
1088
//Allow missing one, just set to empty string.
1006
1089
wrap [ keyName ] = '' ;
1007
- } else if ( typeof wrap [ keyName ] !== 'string' ) {
1090
+ } else if ( typeof wrap [ keyName ] === 'string' ) {
1091
+ wrap [ keyName ] = endsWithNewLine ( wrap [ keyName ] ) ;
1092
+ wrap [ keyMapName ] = [
1093
+ function ( fileContents , cfg , sourceMapGenerator ) {
1094
+ var absPath = build . makeAbsPath ( "config-wrap-" + keyName + "-default.js" , absFilePath ) ;
1095
+ return appendToFileContents ( fileContents , wrap [ keyName ] , absPath , cfg , null , sourceMapGenerator ) ;
1096
+ }
1097
+ ] ;
1098
+ } else {
1008
1099
throw new Error ( 'wrap.' + keyName + ' or wrap.' + keyFileName + ' malformed' ) ;
1009
1100
}
1010
1101
}
@@ -1016,12 +1107,27 @@ define(function (require) {
1016
1107
if ( config . wrap === true ) {
1017
1108
//Use default values.
1018
1109
config . wrap = {
1019
- start : '(function () {' ,
1020
- end : '}());'
1110
+ start : '(function () {\n' ,
1111
+ end : '}());' ,
1112
+ __startMap : [
1113
+ function ( fileContents , cfg , sourceMapGenerator ) {
1114
+ return appendToFileContents ( fileContents , "(function () {\n" ,
1115
+ build . makeAbsPath ( "config-wrap-start-default.js" ,
1116
+ absFilePath ) , cfg , null ,
1117
+ sourceMapGenerator ) ;
1118
+ }
1119
+ ] ,
1120
+ __endMap : [
1121
+ function ( fileContents , cfg , sourceMapGenerator ) {
1122
+ return appendToFileContents ( fileContents , "}());" ,
1123
+ build . makeAbsPath ( "config-wrap-end-default.js" , absFilePath ) ,
1124
+ cfg , null , sourceMapGenerator ) ;
1125
+ }
1126
+ ]
1021
1127
} ;
1022
1128
} else {
1023
- flattenWrapFile ( config . wrap , 'start' , absFilePath ) ;
1024
- flattenWrapFile ( config . wrap , 'end' , absFilePath ) ;
1129
+ flattenWrapFile ( config , 'start' , absFilePath ) ;
1130
+ flattenWrapFile ( config , 'end' , absFilePath ) ;
1025
1131
}
1026
1132
}
1027
1133
} catch ( wrapError ) {
@@ -1781,11 +1887,16 @@ define(function (require) {
1781
1887
} ) ;
1782
1888
1783
1889
//Write the built module to disk, and build up the build output.
1784
- fileContents = config . wrap ? config . wrap . start : "" ;
1890
+ fileContents = "" ;
1891
+ if ( config . wrap && config . wrap . __startMap ) {
1892
+ config . wrap . __startMap . forEach ( function ( wrapFunction ) {
1893
+ fileContents = wrapFunction ( fileContents , config , sourceMapGenerator ) ;
1894
+ } ) ;
1895
+ }
1896
+
1785
1897
return prim . serial ( layer . buildFilePaths . map ( function ( path ) {
1786
1898
return function ( ) {
1787
- var lineCount ,
1788
- singleContents = '' ;
1899
+ var singleContents = '' ;
1789
1900
1790
1901
moduleName = layer . buildFileToModule [ path ] ;
1791
1902
@@ -1882,9 +1993,7 @@ define(function (require) {
1882
1993
} ) ;
1883
1994
}
1884
1995
} ) . then ( function ( ) {
1885
- var refPath , pluginId , resourcePath , shimDeps ,
1886
- sourceMapPath , sourceMapLineNumber ,
1887
- shortPath = path . replace ( config . dir , "" ) ;
1996
+ var shimDeps , shortPath = path . replace ( config . dir , "" ) ;
1888
1997
1889
1998
module . onCompleteData . included . push ( shortPath ) ;
1890
1999
buildFileContents += shortPath + "\n" ;
@@ -1931,66 +2040,24 @@ define(function (require) {
1931
2040
//for concatenation would cause an error otherwise.
1932
2041
singleContents += '\n' ;
1933
2042
1934
- //Add to the source map
1935
- if ( sourceMapGenerator ) {
1936
- refPath = config . out ? config . baseUrl : module . _buildPath ;
1937
- parts = path . split ( '!' ) ;
1938
- if ( parts . length === 1 ) {
1939
- //Not a plugin resource, fix the path
1940
- sourceMapPath = build . makeRelativeFilePath ( refPath , path ) ;
1941
- } else {
1942
- //Plugin resource. If it looks like just a plugin
1943
- //followed by a module ID, pull off the plugin
1944
- //and put it at the end of the name, otherwise
1945
- //just leave it alone.
1946
- pluginId = parts . shift ( ) ;
1947
- resourcePath = parts . join ( '!' ) ;
1948
- if ( resourceIsModuleIdRegExp . test ( resourcePath ) ) {
1949
- sourceMapPath = build . makeRelativeFilePath ( refPath , require . toUrl ( resourcePath ) ) +
1950
- '!' + pluginId ;
1951
- } else {
1952
- sourceMapPath = path ;
1953
- }
1954
- }
1955
-
1956
- sourceMapLineNumber = fileContents . split ( '\n' ) . length - 1 ;
1957
- lineCount = singleContents . split ( '\n' ) . length ;
1958
- for ( var i = 1 ; i <= lineCount ; i += 1 ) {
1959
- sourceMapGenerator . addMapping ( {
1960
- generated : {
1961
- line : sourceMapLineNumber + i ,
1962
- column : 0
1963
- } ,
1964
- original : {
1965
- line : i ,
1966
- column : 0
1967
- } ,
1968
- source : sourceMapPath
1969
- } ) ;
1970
- }
1971
-
1972
- //Store the content of the original in the source
1973
- //map since other transforms later like minification
1974
- //can mess up translating back to the original
1975
- //source.
1976
- sourceMapGenerator . setSourceContent ( sourceMapPath , singleContents ) ;
1977
- }
1978
-
1979
- //Add the file to the final contents
1980
- fileContents += singleContents ;
2043
+ //Add to the source map and to the final contents
2044
+ fileContents = appendToFileContents ( fileContents , singleContents , path , config , module ,
2045
+ sourceMapGenerator ) ;
1981
2046
} ) ;
1982
2047
} ;
1983
2048
} ) ) . then ( function ( ) {
1984
2049
if ( onLayerEnds . length ) {
1985
- onLayerEnds . forEach ( function ( builder ) {
2050
+ onLayerEnds . forEach ( function ( builder , index ) {
1986
2051
var path ;
1987
2052
if ( typeof module . out === 'string' ) {
1988
2053
path = module . out ;
1989
2054
} else if ( typeof module . _buildPath === 'string' ) {
1990
2055
path = module . _buildPath ;
1991
2056
}
1992
2057
builder . onLayerEnd ( function ( input ) {
1993
- fileContents += "\n" + addSemiColon ( input , config ) ;
2058
+ fileContents =
2059
+ appendToFileContents ( fileContents , "\n" + addSemiColon ( input , config ) ,
2060
+ 'onLayerEnd' + index + '.js' , config , module , sourceMapGenerator ) ;
1994
2061
} , {
1995
2062
name : module . name ,
1996
2063
path : path
@@ -2003,21 +2070,30 @@ define(function (require) {
2003
2070
//a module definition for it in case the
2004
2071
//built file is used with enforceDefine
2005
2072
//(#432)
2006
- fileContents += '\n' + namespaceWithDot + 'define("' + module . name + '", function(){});\n' ;
2073
+ fileContents =
2074
+ appendToFileContents ( fileContents , '\n' + namespaceWithDot + 'define("' + module . name +
2075
+ '", function(){});\n' , 'module-create.js' , config , module ,
2076
+ sourceMapGenerator ) ;
2007
2077
}
2008
2078
2009
2079
//Add a require at the end to kick start module execution, if that
2010
2080
//was desired. Usually this is only specified when using small shim
2011
2081
//loaders like almond.
2012
2082
if ( module . insertRequire ) {
2013
- fileContents += '\n' + namespaceWithDot + 'require(["' + module . insertRequire . join ( '", "' ) + '"]);\n' ;
2083
+ fileContents =
2084
+ appendToFileContents ( fileContents , '\n' + namespaceWithDot + 'require(["' + module . insertRequire . join ( '", "' ) +
2085
+ '"]);\n' , 'module-insertRequire.js' , config , module ,
2086
+ sourceMapGenerator ) ;
2014
2087
}
2015
2088
} ) ;
2016
2089
} ) . then ( function ( ) {
2090
+ if ( config . wrap && config . wrap . __endMap ) {
2091
+ config . wrap . __endMap . forEach ( function ( wrapFunction ) {
2092
+ fileContents = wrapFunction ( fileContents , config , sourceMapGenerator ) ;
2093
+ } ) ;
2094
+ }
2017
2095
return {
2018
- text : config . wrap ?
2019
- fileContents + config . wrap . end :
2020
- fileContents ,
2096
+ text : fileContents ,
2021
2097
buildText : buildFileContents ,
2022
2098
sourceMap : sourceMapGenerator ?
2023
2099
JSON . stringify ( sourceMapGenerator . toJSON ( ) , null , ' ' ) :
0 commit comments