How to copy required node modules to target dir with gulp?

One of the common tasks related to node.js development is building production ready package. Sometimes you just need to clean and install production only scripts but sometimes you need something more complicated like preparing files for electron package. And one of important part is to copy correct node modules to target locations. By correct node modules I mean production dependencies without dev dependencies. Taking into account complicated algorithm of node modules installation it may be not trivial task.

I have tried several approaches like reading package.json and extracting list of dependencies, but in that case you can’t just copy modules listed in dependencies, you have to copy dependencies recursively according to algorithm. As for me the most optimal solution is to give npm to deal with all modules by itself. The main idea is to install node modules with –production parameter to some cache folder and then copy modules with every build to target folder. To simplify call of npm install I used gulp-install, but you can do everything with gulp-exec.

Here is my tasks configuration:

[code lang=js]
const gulp = require("gulp");
const ts = require("gulp-typescript");
const install = require("gulp-install");
// I need other info from package.json so let's load it as object
const package = require("./package.json");

// Copy node modules from cache with cache refresh
gulp.task("node_modules", ["node_modules_cache"], () => {
gulp.src("./build/modules/node_modules/**/*.*", {base: "./build/modules/node_modules/"})

gulp.task("node_modules_cache", () => {
// Ensure directory exists

// You can replace following by just copy package.json, but I have already loaded it so let's just save
fs.writeFileSync("./build/modules/package.json", JSON.stringify(package));

// Make npm install in cache location
return gulp.src("./build/modules/package.json")
.pipe(install({production: true}));

I’m trying to install scripts content and node_modules to ./build/debug/resources/app/ because I’m assembling electron app at ./build/debug/. After that I’m calling gulp-electron to prepare final application and even change icon of electron.exe file but that is another story…