Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ryan778
GitHub Repository: Ryan778/Ryan778.github.io
Path: blob/master/emojionearea/tasks/build.js
575 views
1
/**
2
* Special concat/build task to handle build requirements
3
* Concats AMD modules, removes their definitions,
4
* and includes/excludes specified modules
5
*/
6
7
module.exports = function( grunt ) {
8
"use strict";
9
10
var fs = require( "fs" ),
11
requirejs = require( "requirejs" ),
12
pkg = require( "../package.json" ),
13
srcFolder = __dirname + "/../src/",
14
rdefineEnd = /\n\}\s*?\);[^}\w]*$/,
15
read = function( fileName ) {
16
return grunt.file.read( srcFolder + fileName );
17
},
18
wrapper = read( "wrapper.js" ).split( /\/\/ \@CODE\n\/\/[^\n]+\n/ ),
19
config = {
20
baseUrl: "src",
21
name: pkg.name,
22
23
paths: {
24
jquery : 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min'
25
},
26
27
// We have multiple minify steps
28
optimize: "none",
29
30
// Include dependencies loaded with require
31
findNestedDependencies: true,
32
33
// Avoid inserting define() placeholder
34
skipModuleInsertion: true,
35
36
// Avoid breaking semicolons inserted by r.js
37
skipSemiColonInsertion: true,
38
wrap: {
39
start: wrapper[ 0 ].replace( /\/\*jshint .* \*\/\n/, "" ),
40
end: wrapper[ 1 ]
41
},
42
rawText: {},
43
onBuildWrite: convert
44
};
45
46
/**
47
* Strip all definitions generated by requirejs
48
* Convert "var" modules to var declarations
49
* "var module" means the module only contains a return
50
* statement that should be converted to a var declaration
51
* This is indicated by including the file in any "var" folder
52
* @param {String} name
53
* @param {String} path
54
* @param {String} contents The contents to be written (including their AMD wrappers)
55
*/
56
function convert( name, path, contents ) {
57
var amdName;
58
59
// Convert var modules
60
if ( /.\/var\//.test( path.replace( process.cwd(), "" ) ) ) {
61
contents = contents
62
.replace( /define\([\w\W]*?return undefined\s*;/, " var " + ( /var\/([\w-]+)/.exec( name )[ 1 ] ) + ";" )
63
.replace( /define\([\w\W]*?return/, " var " + ( /var\/([\w-]+)/.exec( name )[ 1 ] ) + " =" )
64
.replace( rdefineEnd, "" );
65
66
} else if ( /.\/function\//.test( path.replace( process.cwd(), "" ) ) ) {
67
contents = contents
68
.replace( /define\([\w\W]*?return function/, " function " + ( /function\/([\w-]+)/.exec( name )[ 1 ] ) + "")
69
.replace( rdefineEnd, "" );
70
71
// Remove empty definitions
72
contents = contents
73
.replace( /define\(\[[^\]]*\]\)[\W\n]+$/, "" );
74
75
} else {
76
contents = contents
77
.replace( /\s*return\s+[^\}]+(\}\s*?\);[^\w\}]*)$/, "$1" )
78
79
// Multiple exports
80
.replace( /\s*exports\.\w+\s*=\s*\w+;/g, "" );
81
82
// Remove define wrappers, closure ends, and empty declarations
83
contents = contents
84
.replace( /define\([^{]*?{/, "" )
85
.replace( rdefineEnd, "" );
86
87
// Remove anything wrapped with
88
// /* ExcludeStart */ /* ExcludeEnd */
89
// or a single line directly after a // BuildExclude comment
90
contents = contents
91
.replace( /\/\*\s*ExcludeStart\s*\*\/[\w\W]*?\/\*\s*ExcludeEnd\s*\*\//ig, "" )
92
.replace( /\/\/\s*BuildExclude\n\r?[\w\W]*?\n\r?/ig, "" );
93
94
// Remove empty definitions
95
contents = contents
96
.replace( /define\(\[[^\]]*\]\)[\W\n]+$/, "" );
97
}
98
99
// AMD Name
100
if ( ( amdName = grunt.option( "amd" ) ) != null && /^exports\/amd$/.test( name ) ) {
101
102
// Remove the comma for anonymous defines
103
contents = contents
104
.replace( new RegExp('/(\s*)"' + pkg.name + '"(\,\s*)/'),
105
amdName ? "$1\"" + amdName + "\"$2" : "" );
106
107
}
108
return contents;
109
}
110
111
grunt.registerMultiTask(
112
"build",
113
"Concatenate source, remove sub AMD definitions, " +
114
"(include/exclude modules with +/- flags), embed date/version",
115
function() {
116
var flag, index,
117
done = this.async(),
118
flags = this.flags,
119
name = grunt.option( "filename" ),
120
minimum = this.data.minimum,
121
removeWith = this.data.removeWith,
122
excluded = [],
123
included = [],
124
version = grunt.config( "pkg.version" ),
125
/**
126
* Recursively calls the excluder to remove on all modules in the list
127
* @param {Array} list
128
* @param {String} [prepend] Prepend this to the module name.
129
* Indicates we're walking a directory
130
*/
131
excludeList = function( list, prepend ) {
132
if ( list ) {
133
prepend = prepend ? prepend + "/" : "";
134
list.forEach( function( module ) {
135
136
// Exclude var modules as well
137
if ( module === "var" ) {
138
excludeList(
139
fs.readdirSync( srcFolder + prepend + module ), prepend + module
140
);
141
return;
142
}
143
if ( prepend ) {
144
145
// Skip if this is not a js file and we're walking files in a dir
146
if ( !( module = /([\w-\/]+)\.js$/.exec( module ) ) ) {
147
return;
148
}
149
150
// Prepend folder name if passed
151
// Remove .js extension
152
module = prepend + module[ 1 ];
153
}
154
155
// Avoid infinite recursion
156
if ( excluded.indexOf( module ) === -1 ) {
157
excluder( "-" + module );
158
}
159
} );
160
}
161
},
162
/**
163
* Adds the specified module to the excluded or included list, depending on the flag
164
* @param {String} flag A module path relative to
165
* the src directory starting with + or - to indicate
166
* whether it should included or excluded
167
*/
168
excluder = function( flag ) {
169
var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
170
exclude = m[ 1 ] === "-",
171
module = m[ 2 ];
172
173
if ( exclude ) {
174
175
// Can't exclude certain modules
176
if ( minimum.indexOf( module ) === -1 ) {
177
178
// Add to excluded
179
if ( excluded.indexOf( module ) === -1 ) {
180
grunt.log.writeln( flag );
181
excluded.push( module );
182
183
// Exclude all files in the folder of the same name
184
// These are the removable dependencies
185
// It's fine if the directory is not there
186
try {
187
excludeList( fs.readdirSync( srcFolder + module ), module );
188
} catch ( e ) {
189
grunt.verbose.writeln( e );
190
}
191
}
192
193
// Check removeWith list
194
excludeList( removeWith[ module ] );
195
} else {
196
grunt.log.error( "Module \"" + module + "\" is a minimum requirement." );
197
if ( module === "selector" ) {
198
grunt.log.error(
199
"If you meant to replace Sizzle, use -sizzle instead."
200
);
201
}
202
}
203
} else {
204
grunt.log.writeln( flag );
205
included.push( module );
206
}
207
};
208
209
// Filename can be passed to the command line using
210
// command line options
211
name = name ? ( "dist/" + name ) : this.data.dest;
212
213
// append commit id to version
214
if ( process.env.COMMIT ) {
215
version += " " + process.env.COMMIT;
216
}
217
218
// figure out which files to exclude based on these rules in this order:
219
// dependency explicit exclude
220
delete flags[ "*" ];
221
for ( flag in flags ) {
222
excluder( flag );
223
}
224
225
grunt.verbose.writeflags( excluded, "Excluded" );
226
grunt.verbose.writeflags( included, "Included" );
227
228
// append excluded modules to version
229
if ( excluded.length ) {
230
version += " -" + excluded.join( ",-" );
231
232
// set pkg.version to version with excludes, so minified file picks it up
233
grunt.config.set( "pkg.version", version );
234
grunt.verbose.writeln( "Version changed to " + version );
235
236
// Have to use shallow or core will get excluded since it is a dependency
237
config.excludeShallow = excluded;
238
}
239
config.include = included;
240
241
/**
242
* Handle Final output from the optimizer
243
* @param {String} compiled
244
*/
245
config.out = function( compiled ) {
246
compiled = compiled
247
248
// Embed Version
249
.replace( /@VERSION/g, version )
250
251
// Embed Date
252
// yyyy-mm-ddThh:mmZ
253
.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
254
255
// Write concatenated source to file
256
grunt.file.write( name, compiled );
257
};
258
259
// Trace dependencies and concatenate files
260
requirejs.optimize( config, function( response ) {
261
grunt.verbose.writeln( response );
262
grunt.log.ok( "File '" + name + "' created." );
263
done();
264
}, function( err ) {
265
done( err );
266
} );
267
} );
268
};
269
270