Index: Gruntfile.js
===================================================================
--- Gruntfile.js	(revision 31387)
+++ Gruntfile.js	(working copy)
@@ -117,11 +117,23 @@
 			}
 		},
 		browserify: {
-			media: {
+			mediaModels: {
+				files: {
+					'src/wp-includes/js/media/models.js' : [ SOURCE_DIR + 'wp-includes/js/media/models.manifest.js' ]
+				}
+			},
+			mediaViews: {
+				files: {
+					'src/wp-includes/js/media/views.js' : [ SOURCE_DIR + 'wp-includes/js/media/views.manifest.js' ]
+				}
+			},
+			mediaAV: {
+				files: {
+					'src/wp-includes/js/media/audio-video.js' : [ SOURCE_DIR + 'wp-includes/js/media/audio-video.manifest.js' ]
+				}
+			},
+			mediaGrid: {
 				files: {
-					'src/wp-includes/js/media/models.js' : [ SOURCE_DIR + 'wp-includes/js/media/models.manifest.js' ],
-					'src/wp-includes/js/media/views.js' : [ SOURCE_DIR + 'wp-includes/js/media/views.manifest.js' ],
-					'src/wp-includes/js/media/audio-video.js' : [ SOURCE_DIR + 'wp-includes/js/media/audio-video.manifest.js' ],
 					'src/wp-includes/js/media/grid.js' : [ SOURCE_DIR + 'wp-includes/js/media/grid.manifest.js' ]
 				}
 			}
@@ -526,16 +538,42 @@
 		'jshint:media'
 	] );
 
+	grunt.registerTask( 'watchify', function() {
+		grunt.config( 'browserify.options', {
+			browserifyOptions: {
+				debug: true
+			},
+			watch: true
+		} );
+
+		grunt.config( 'browserify.mediaGrid.options', {
+			keepAlive: true
+		} );
+
+		grunt.task.run( [
+			'browserify'
+			// Any grunt watch task can go here,
+			// but the keepAlive option needs to be false.
+		] );
+	} );
+
 	// Pre-commit task.
-	grunt.registerTask('precommit', 'Runs front-end dev/test tasks in preparation for a commit.',
-		['autoprefixer:core', 'imagemin:core', 'jshint:corejs', 'qunit:compiled']);
+	// Advised to run before uploading a patch also.
+	grunt.registerTask( 'precommit', 'Runs front-end dev/test tasks in preparation for a commit.', [
+		'autoprefixer:core',
+		'imagemin:core',
+		// Make sure we don't commit files with debug information.
+		'browserify',
+		'jshint:corejs',
+		'qunit:compiled'
+	] );
 
 	// Copy task.
 	grunt.registerTask('copy:all', ['copy:files', 'copy:wp-admin-rtl', 'copy:version']);
 
 	// Build task.
 	grunt.registerTask('build', ['clean:all', 'copy:all', 'cssmin:core', 'colors', 'rtl', 'cssmin:rtl', 'cssmin:colors',
-		'browserify:media', 'uglify:core', 'uglify:media', 'uglify:jqueryui', 'concat:tinymce', 'compress:tinymce',
+		'browserify', 'uglify:core', 'uglify:media', 'uglify:jqueryui', 'concat:tinymce', 'compress:tinymce',
 		'clean:tinymce', 'jsvalidate:build']);
 
 	// Testing tasks.
