|
10 | 10 | var lodash = require(path.join(__dirname, 'lodash')),
|
11 | 11 | minify = require(path.join(__dirname, 'build', 'minify'));
|
12 | 12 |
|
13 |
| - /** Flag used to specify a custom build */ |
14 |
| - var isCustom = false; |
15 |
| - |
16 | 13 | /** Shortcut used to convert array-like objects to arrays */
|
17 | 14 | var slice = [].slice;
|
18 | 15 |
|
|
141 | 138 | 'zip': ['max', 'pluck']
|
142 | 139 | };
|
143 | 140 |
|
| 141 | + /** Names of methods to filter for the build */ |
| 142 | + var filterMethods = Object.keys(dependencyMap); |
| 143 | + |
| 144 | + /** Used to specify if `filterMethods` should be used for exclusion or inclusion */ |
| 145 | + var filterType = process.argv.reduce(function(result, value) { |
| 146 | + if (!result) { |
| 147 | + var pair = value.match(/^(exclude|include)=(.*)$/); |
| 148 | + if (pair) { |
| 149 | + filterMethods = lodash.intersection(filterMethods, pair[2].split(/, */).map(getRealName)); |
| 150 | + return pair[1]; |
| 151 | + } |
| 152 | + } |
| 153 | + }, ''); |
| 154 | + |
| 155 | + /** Flag used to specify a mobile build */ |
| 156 | + var isMobile = process.argv.indexOf('mobile') > -1; |
| 157 | + |
144 | 158 | /*--------------------------------------------------------------------------*/
|
145 | 159 |
|
146 | 160 | /**
|
|
344 | 358 | /*--------------------------------------------------------------------------*/
|
345 | 359 |
|
346 | 360 | // custom build
|
347 |
| - process.argv.some(function(arg) { |
348 |
| - // exit early if not the "exclude" or "include" command option |
349 |
| - var pair = arg.match(/^(exclude|include)=(.*)$/); |
350 |
| - if (!pair) { |
351 |
| - return false; |
| 361 | + (function() { |
| 362 | + // exit early if "exclude" or "include" options aren't specified |
| 363 | + if (!filterType) { |
| 364 | + return; |
352 | 365 | }
|
353 |
| - |
354 |
| - var filterType = pair[1], |
355 |
| - filterNames = lodash.intersection(Object.keys(dependencyMap), pair[2].split(/, */).map(getRealName)); |
356 |
| - |
357 |
| - // set custom build flag |
358 |
| - isCustom = true; |
359 |
| - |
360 | 366 | // remove the specified functions and their dependants
|
361 | 367 | if (filterType == 'exclude') {
|
362 |
| - filterNames.forEach(function(funcName) { |
| 368 | + filterMethods.forEach(function(funcName) { |
363 | 369 | getDependants(funcName).concat(funcName).forEach(function(otherName) {
|
364 | 370 | source = removeFunction(source, otherName);
|
365 | 371 | });
|
366 | 372 | });
|
367 | 373 | }
|
368 | 374 | // else remove all but the specified functions and their dependencies
|
369 | 375 | else {
|
370 |
| - filterNames = lodash.uniq(filterNames.reduce(function(result, funcName) { |
| 376 | + filterMethods = lodash.uniq(filterMethods.reduce(function(result, funcName) { |
371 | 377 | result.push.apply(result, getDependencies(funcName).concat(funcName));
|
372 | 378 | return result;
|
373 | 379 | }, []));
|
374 | 380 |
|
375 | 381 | lodash.each(dependencyMap, function(dependencies, otherName) {
|
376 |
| - if (filterNames.indexOf(otherName) < 0) { |
| 382 | + if (filterMethods.indexOf(otherName) < 0) { |
377 | 383 | source = removeFunction(source, otherName);
|
378 | 384 | }
|
379 | 385 | });
|
|
402 | 408 | if (isRemoved(source, 'bind', 'functions', 'groupBy', 'invoke', 'isEqual', 'isFunction', 'result', 'sortBy', 'toArray')) {
|
403 | 409 | source = removeVar(source, 'funcClass');
|
404 | 410 | }
|
| 411 | + if (isRemoved(source, 'bind')) { |
| 412 | + source = removeVar(source, 'nativeBind'); |
| 413 | + } |
| 414 | + if (isRemoved(source, 'isArray')) { |
| 415 | + source = removeVar(source, 'nativeIsArray'); |
| 416 | + } |
| 417 | + if (isRemoved(source, 'keys')) { |
| 418 | + source = removeVar(source, 'nativeKeys'); |
| 419 | + } |
405 | 420 | if (isRemoved(source, 'clone', 'isObject', 'keys')) {
|
406 | 421 | source = removeVar(source, 'objectTypes');
|
407 | 422 | source = removeFromCreateIterator(source, 'objectTypes');
|
408 | 423 | }
|
| 424 | + if (isRemoved(source, 'bind', 'isArray', 'keys')) { |
| 425 | + source = removeVar(source, 'reNative'); |
| 426 | + } |
409 | 427 | if (isRemoved(source, 'isEmpty', 'isEqual', 'isString', 'size')) {
|
410 | 428 | source = removeVar(source, 'stringClass');
|
411 | 429 | }
|
|
414 | 432 | source = source.replace(/(?:\s*\/\*-+\*\/\s*){2,}/g, function(separators) {
|
415 | 433 | return separators.match(/^\s*/)[0] + separators.slice(separators.lastIndexOf('/*'));
|
416 | 434 | });
|
417 |
| - |
418 |
| - return true; |
419 |
| - }); |
| 435 | + }()); |
420 | 436 |
|
421 | 437 | /*--------------------------------------------------------------------------*/
|
422 | 438 |
|
423 |
| - (function() { |
424 |
| - // for mobile builds |
425 |
| - if (process.argv.indexOf('mobile') > -1) { |
426 |
| - // set custom build flag |
427 |
| - isCustom = true; |
428 |
| - |
429 |
| - // inline functions defined with `createIterator` |
430 |
| - lodash.functions(lodash).forEach(function(funcName) { |
431 |
| - var reFunc = RegExp('( +var ' + funcName + ' *= *)((?:[a-zA-Z]+ *\\|\\| *)?)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n'), |
432 |
| - parts = source.match(reFunc); |
433 |
| - |
434 |
| - // skip if not defined with `createIterator` |
435 |
| - if (!parts) { |
436 |
| - return; |
437 |
| - } |
438 |
| - source = source.replace(reFunc, |
439 |
| - (funcName == 'keys' |
440 |
| - ? '$1$2' + lodash._createIterator(Function('return ' + parts[3])()) |
441 |
| - : '$1' + lodash[funcName] |
442 |
| - ) + ';\n' |
443 |
| - ); |
444 |
| - }); |
| 439 | + if (isMobile) { |
| 440 | + // inline functions defined with `createIterator` |
| 441 | + lodash.functions(lodash).forEach(function(funcName) { |
| 442 | + var reFunc = RegExp('( +var ' + funcName + ' *= *)((?:[a-zA-Z]+ *\\|\\| *)?)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n'), |
| 443 | + parts = source.match(reFunc); |
445 | 444 |
|
446 |
| - // remove `iteratorTemplate` |
447 |
| - source = removeVar(source, 'iteratorTemplate'); |
448 |
| - |
449 |
| - // remove JScript [[DontEnum]] fix from `isEqual` |
450 |
| - source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}\n/, '\n'); |
451 |
| - } |
452 |
| - // for normal builds |
453 |
| - else { |
454 |
| - // extract `iteratorTemplate` source |
455 |
| - var iteratorTemplateCode = /^function[^{]+{([\s\S]+?)}$/.exec(lodash._iteratorTemplate)[1]; |
| 445 | + // skip if not defined with `createIterator` |
| 446 | + if (!parts) { |
| 447 | + return; |
| 448 | + } |
| 449 | + // extract function's code |
| 450 | + var code = funcName == 'keys' |
| 451 | + ? '$1$2' + lodash._createIterator(Function('return ' + parts[3])()) |
| 452 | + : '$1' + lodash[funcName]; |
| 453 | + |
| 454 | + // format code |
| 455 | + code = code.replace(/\n(?:.*)/g, function(match) { |
| 456 | + match = match.slice(1); |
| 457 | + return (match == '}' ? '\n ' : '\n ') + match; |
| 458 | + }) + ';\n'; |
| 459 | + |
| 460 | + source = source.replace(reFunc, code); |
| 461 | + }); |
456 | 462 |
|
457 |
| - // remove whitespace and unnecessary code |
458 |
| - iteratorTemplateCode = removeWhitespace(iteratorTemplateCode) |
459 |
| - .replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '') |
460 |
| - .replace(/(\{);|;(\})/g, '$1$2') |
461 |
| - .replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1'); |
| 463 | + // remove `iteratorTemplate` |
| 464 | + source = removeVar(source, 'iteratorTemplate'); |
462 | 465 |
|
463 |
| - // ensure escaped characters are interpreted correctly inside the `Function()` string |
464 |
| - iteratorTemplateCode = iteratorTemplateCode.replace(/\\/g, '\\\\'); |
| 466 | + // remove JScript [[DontEnum]] fix from `isEqual` |
| 467 | + source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}\n/, '\n'); |
465 | 468 |
|
466 |
| - // add `iteratorTemplateCode` to `Function()` to avoid strict mode error |
467 |
| - // for using a with-statement |
468 |
| - iteratorTemplateCode = '$1Function(\'object\',\n$2 "' + iteratorTemplateCode + '"\n$2);\n'; |
| 469 | + // remove IE `shift` and `splice` fix |
| 470 | + source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(value.length *=== *0[\s\S]+?\n\1}\n/, '\n'); |
| 471 | + } |
| 472 | + else { |
| 473 | + // inline `iteratorTemplate` template |
| 474 | + source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, (function() { |
| 475 | + // extract `iteratorTemplate` code |
| 476 | + var code = /^function[^{]+{([\s\S]+?)}$/.exec(lodash._iteratorTemplate)[1]; |
469 | 477 |
|
470 |
| - // replace `template()` with `Function()` |
471 |
| - source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, iteratorTemplateCode); |
472 |
| - } |
| 478 | + code = removeWhitespace(code) |
| 479 | + // remove unnecessary code |
| 480 | + .replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '') |
| 481 | + .replace(/(\{);|;(\})/g, '$1$2') |
| 482 | + .replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1') |
| 483 | + // ensure escaped characters are interpreted correctly in the string literal |
| 484 | + .replace(/\\/g, '\\\\'); |
| 485 | + |
| 486 | + // add `code` to `Function()` as a string literal to avoid strict mode |
| 487 | + // errors caused by the required with-statement |
| 488 | + return '$1Function(\'obj\',\n$2 "' + code + '"\n$2);\n'; |
| 489 | + }())); |
| 490 | + } |
473 | 491 |
|
474 |
| - // remove pseudo private properties |
475 |
| - source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._(?:createIterator|iteratorTemplate)\b.+\n/g, '\n'); |
476 |
| - }()); |
| 492 | + // remove pseudo private properties |
| 493 | + source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._(?:createIterator|iteratorTemplate)\b.+\n/g, '\n'); |
477 | 494 |
|
478 | 495 | /*--------------------------------------------------------------------------*/
|
479 | 496 |
|
480 | 497 | // begin the minification process
|
481 |
| - if (isCustom) { |
| 498 | + if (filterType || isMobile) { |
482 | 499 | fs.writeFileSync(path.join(__dirname, 'lodash.custom.js'), source);
|
483 | 500 | minify(source, 'lodash.custom.min', function(result) {
|
484 | 501 | fs.writeFileSync(path.join(__dirname, 'lodash.custom.min.js'), result);
|
|
0 commit comments