var exec = require('child_process').exec; var chalk = require('chalk'); var path = require('path'); var _ = require('underscore'); var fs = require('fs-extra'); module.exports = function(grunt) { var getModuleKeys = function(data) { var list = []; _.each(data, function(dep, key){ if (!dep.extraneous) { list.push(key); if (dep.dependencies) { list = list.concat(getModuleKeys(dep.dependencies)); } } }); return list; } grunt.registerTask('copy-modules', "Copy node modules", function(){ var done = this.async(); // get a JSON structured list of all of our production dependencies exec('npm list --production --json', {maxBuffer: 2000*1024}, function(err, stdout){ var modules = JSON.parse(stdout); // extract the module names of all dependencies and sub-dependencies var dependencies = getModuleKeys(modules.dependencies); // filter to only modules that are currently in the root, this allows us // to continue using NPM2 without problems dependencies = _.intersection(dependencies, fs.readdirSync('node_modules')); // copy only these directories over to the production app. We need to do // this as NPM3 will put all dependencies in the root of node_modules // instead of nesting them (currently using on Windows). _.each(dependencies, function(key){ fs.copySync('node_modules/' + key, 'cache/app/node_modules/' + key); grunt.verbose.writeln('Copied ' + chalk.cyan(key)); }); grunt.log.writeln('Copied ' + chalk.cyan(dependencies.length) + ' modules'); done(); }); }); }