Skip to content
Permalink
Browse files

Move jQuery specific tasks to independent files. Close gh-1334.

Also:
	* Confirm build task to the style guide
	* Use grunt API to load jQuery specific tasks
	* Add "use strict"; statements
  • Loading branch information...
markelog authored and timmywil committed Aug 16, 2013
1 parent 70c9a0a commit df67c1ab0963c6a05735e84f4088a0f6b7484b3d
Showing with 214 additions and 198 deletions.
  1. +11 −191 Gruntfile.js
  2. +9 −7 build/{ → tasks}/build.js
  3. +90 −0 build/tasks/dist.js
  4. +50 −0 build/tasks/testswarm.js
  5. +54 −0 build/tasks/uglify.js
@@ -2,23 +2,14 @@ module.exports = function( grunt ) {

"use strict";

// Integrate build task
require( "./build/build" )( grunt );

var distpaths = [
"dist/jquery.js",
"dist/jquery.min.map",
"dist/jquery.min.js"
],
gzip = require("gzip-js"),
var gzip = require( "gzip-js" ),
readOptionalJSON = function( filepath ) {
var data = {};
try {
data = grunt.file.readJSON( filepath );
} catch(e) {}
return data;
},
fs = require( "fs" ),
srcHintOptions = readOptionalJSON( "src/.jshintrc" );

// The concatenated file won't pass onevar
@@ -68,7 +59,7 @@ module.exports = function( grunt ) {
options: srcHintOptions
},
grunt: {
src: [ "Gruntfile.js", "build/build.js" ],
src: [ "Gruntfile.js", "build/tasks/*" ],
options: {
jshintrc: ".jshintrc"
}
@@ -138,187 +129,16 @@ module.exports = function( grunt ) {
}
});

grunt.registerTask( "testswarm", function( commit, configFile ) {
var jobName,
testswarm = require( "testswarm" ),
runs = {},
done = this.async(),
pull = /PR-(\d+)/.exec( commit ),
config = grunt.file.readJSON( configFile ).jquery,
tests = grunt.config([ this.name, "tests" ]);

if ( pull ) {
jobName = "jQuery pull <a href='https://github.com/jquery/jquery/pull/" +
pull[ 1 ] + "'>#" + pull[ 1 ] + "</a>";
} else {
jobName = "jQuery commit #<a href='https://github.com/jquery/jquery/commit/" +
commit + "'>" + commit.substr( 0, 10 ) + "</a>";
}

tests.forEach(function( test ) {
runs[test] = config.testUrl + commit + "/test/index.html?module=" + test;
});

// TODO: create separate job for git/git2 so we can do different browsersets
testswarm.createClient( {
url: config.swarmUrl,
pollInterval: 10000,
timeout: 1000 * 60 * 30
} )
.addReporter( testswarm.reporters.cli )
.auth( {
id: config.authUsername,
token: config.authToken
})
.addjob(
{
name: jobName,
runs: runs,
runMax: config.runMax,
browserSets: "popular-no-old-ie"
}, function( err, passed ) {
if ( err ) {
grunt.log.error( err );
}
done( passed );
}
);
});

// Process files for distribution
grunt.registerTask( "dist", function() {
var stored, flags, paths, nonascii;

// Check for stored destination paths
// ( set in dist/.destination.json )
stored = Object.keys( grunt.config( "dst" ) );

// Allow command line input as well
flags = Object.keys( this.flags );

// Combine all output target paths
paths = [].concat( stored, flags ).filter(function( path ) {
return path !== "*";
});

// Ensure the dist files are pure ASCII
nonascii = false;

distpaths.forEach(function( filename ) {
var i, c,
text = fs.readFileSync( filename, "utf8" );

// Ensure files use only \n for line endings, not \r\n
if ( /\x0d\x0a/.test( text ) ) {
grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" );
nonascii = true;
}

// Ensure only ASCII chars so script tags don't need a charset attribute
if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
grunt.log.writeln( filename + ": Non-ASCII characters detected:" );
for ( i = 0; i < text.length; i++ ) {
c = text.charCodeAt( i );
if ( c > 127 ) {
grunt.log.writeln( "- position " + i + ": " + c );
grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) );
break;
}
}
nonascii = true;
}

// Modify map/min so that it points to files in the same folder;
// see https://github.com/mishoo/UglifyJS2/issues/47
if ( /\.map$/.test( filename ) ) {
text = text.replace( /"dist\//g, "\"" );
fs.writeFileSync( filename, text, "utf-8" );

// Use our hard-coded sourceMap directive instead of the autogenerated one (#13274; #13776)
} else if ( /\.min\.js$/.test( filename ) ) {
i = 0;
text = text.replace( /(?:\/\*|)\n?\/\/@\s*sourceMappingURL=.*(\n\*\/|)/g,
function( match ) {
if ( i++ ) {
return "";
}
return match;
});
fs.writeFileSync( filename, text, "utf-8" );
}

// Optionally copy dist files to other locations
paths.forEach(function( path ) {
var created;

if ( !/\/$/.test( path ) ) {
path += "/";
}

created = path + filename.replace( "dist/", "" );
grunt.file.write( created, text );
grunt.log.writeln( "File '" + created + "' created." );
});
});

return !nonascii;
});

// Work around grunt-contrib-uglify sourceMap issues (jQuery #13776)
grunt.registerMultiTask( "pre-uglify", function() {
var banner = this.options().banner;

this.files.forEach(function( mapping ) {
// Join src
var input = mapping.src.map(function( file ) {
var contents = grunt.file.read( file );

// Strip banners
return contents
// Remove the main jQuery banner, it'll be replaced by the new banner anyway.
.replace( /^\/\*![\W\w]*?\*\/\n?/g, "" )
// Strip other banners preserving line count.
.replace( /^\/\*!(?:.|\n)*?\*\/\n?/gm, function ( match ) {
return match.replace( /[^\n]/gm, "" );
});
}).join("\n");

// Write temp file (with optional banner)
grunt.file.write( mapping.dest, ( banner || "" ) + input );
});
});

// Change the map file to point back to jquery.js instead of jquery.pre-min.js.
// The problem is caused by the pre-uglify task.
// Also, remove temporary files.
grunt.registerMultiTask( "post-uglify", function() {
this.files.forEach(function( mapping ) {
var mapFileName = mapping.src[ 0 ];

// Rename the file to a temporary name.
fs.renameSync( mapFileName, mapping.dest);
grunt.file.write( mapFileName, grunt.file.read( mapping.dest )
// The uglify task erroneously prepends dist/ to file names.
.replace( /"dist\//g, "\"" )
// Refer to the source jquery.js, not the temporary jquery.pre-min.js.
.replace( /\.pre-min\./g, "." )
// There's already a pragma at the beginning of the file, remove the one at the end.
.replace( /\/\/@ sourceMappingURL=jquery\.min\.map$/g, "" ));
});

// Remove temporary files.
this.options().tempFiles.forEach(function( fileName ) {
fs.unlink( fileName );
});
});

// Load grunt tasks from NPM packages
grunt.loadNpmTasks("grunt-compare-size");
grunt.loadNpmTasks("grunt-git-authors");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-jsonlint");
grunt.loadNpmTasks( "grunt-compare-size" );
grunt.loadNpmTasks( "grunt-git-authors" );
grunt.loadNpmTasks( "grunt-contrib-watch" );
grunt.loadNpmTasks( "grunt-contrib-jshint" );
grunt.loadNpmTasks( "grunt-contrib-uglify" );
grunt.loadNpmTasks( "grunt-jsonlint" );

// Integrate jQuery specific tasks
grunt.loadTasks( "build/tasks" );

// Short list as a high frequency watch task
grunt.registerTask( "dev", [ "build:*:*", "jshint" ] );
@@ -5,11 +5,13 @@

module.exports = function( grunt ) {

var fs = require("fs"),
"use strict";

var fs = require( "fs" ),
srcFolder = __dirname + "/../src/",
rdefineEnd = /\}\);[^}\w]*$/,
// This is temporary until the skipSemiColonInsertion option makes it to NPM
requirejs = require("./r"),
requirejs = require( "../r" ),
config = {
baseUrl: "src",
name: "jquery",
@@ -114,8 +116,8 @@ module.exports = function( grunt ) {
*/
excluder = function( flag ) {
var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
exclude = m[1] === "-",
module = m[2];
exclude = m[ 1 ] === "-",
module = m[ 2 ];

if ( exclude ) {
// Can't exclude certain modules
@@ -172,7 +174,7 @@ module.exports = function( grunt ) {

// Handle Sizzle exclusion
// Replace with selector-native
if ( (index = excluded.indexOf("sizzle")) > -1 ) {
if ( (index = excluded.indexOf( "sizzle" )) > -1 ) {
config.rawText = {
selector: "define(['./selector-native']);"
};
@@ -228,8 +230,8 @@ module.exports = function( grunt ) {
//
// grunt build:*:*:+ajax:-dimensions:-effects:-offset
grunt.registerTask( "custom", function() {
var args = [].slice.call(arguments),
modules = args.length ? args[0].replace(/,/g, ":") : "";
var args = [].slice.call( arguments ),
modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";

grunt.log.writeln( "Creating custom build...\n" );

@@ -0,0 +1,90 @@
module.exports = function( grunt ) {

"use strict";

var fs = require( "fs" ),
distpaths = [
"dist/jquery.js",
"dist/jquery.min.map",
"dist/jquery.min.js"
];

// Process files for distribution
grunt.registerTask( "dist", function() {
var stored, flags, paths, nonascii;

// Check for stored destination paths
// ( set in dist/.destination.json )
stored = Object.keys( grunt.config( "dst" ) );

// Allow command line input as well
flags = Object.keys( this.flags );

// Combine all output target paths
paths = [].concat( stored, flags ).filter(function( path ) {
return path !== "*";
});

// Ensure the dist files are pure ASCII
nonascii = false;

distpaths.forEach(function( filename ) {
var i, c,
text = fs.readFileSync( filename, "utf8" );

// Ensure files use only \n for line endings, not \r\n
if ( /\x0d\x0a/.test( text ) ) {
grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" );
nonascii = true;
}

// Ensure only ASCII chars so script tags don't need a charset attribute
if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
grunt.log.writeln( filename + ": Non-ASCII characters detected:" );
for ( i = 0; i < text.length; i++ ) {
c = text.charCodeAt( i );
if ( c > 127 ) {
grunt.log.writeln( "- position " + i + ": " + c );
grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) );
break;
}
}
nonascii = true;
}

// Modify map/min so that it points to files in the same folder;
// see https://github.com/mishoo/UglifyJS2/issues/47
if ( /\.map$/.test( filename ) ) {
text = text.replace( /"dist\//g, "\"" );
fs.writeFileSync( filename, text, "utf-8" );

// Use our hard-coded sourceMap directive instead of the autogenerated one (#13274; #13776)
} else if ( /\.min\.js$/.test( filename ) ) {
i = 0;
text = text.replace( /(?:\/\*|)\n?\/\/@\s*sourceMappingURL=.*(\n\*\/|)/g,
function( match ) {
if ( i++ ) {
return "";
}
return match;
});
fs.writeFileSync( filename, text, "utf-8" );
}

// Optionally copy dist files to other locations
paths.forEach(function( path ) {
var created;

if ( !/\/$/.test( path ) ) {
path += "/";
}

created = path + filename.replace( "dist/", "" );
grunt.file.write( created, text );
grunt.log.writeln( "File '" + created + "' created." );
});
});

return !nonascii;
});
};

0 comments on commit df67c1a

Please sign in to comment.
You can’t perform that action at this time.