Skip to content

Instantly share code, notes, and snippets.

@andrewfinnell
Last active September 29, 2016 16:15
Show Gist options
  • Save andrewfinnell/c873f67d1cf41cfc87d8e4b8fb9ff430 to your computer and use it in GitHub Desktop.
Save andrewfinnell/c873f67d1cf41cfc87d8e4b8fb9ff430 to your computer and use it in GitHub Desktop.
symlink node_module dependencies on Windows
/**
* Gulpfile.js
* Symlinks node_module dependencies into any directory. This
* file works on Windows and Linux machines by recursively
* symlinking the files within a node module instead of symlinking
* just the directory. This is vitally important as Editor's on Windows
* do not understand Junctions and therefor will delete all the children
* files first (i.e. the original files from the original directory), a
* disasterous situation, especially if this is used with npm link.
*/
var gulp = require('gulp'),
clean = require('gulp-clean'),
path = require('path'),
fs = require('graceful-fs'),
source = require('vinyl-source-stream'),
through2 = require('through2'),
prepareWrite = require('vinyl-fs/lib/prepareWrite'),
// Project package.json
PACKAGE_JSON = JSON.parse (fs.readFileSync ('./package.json')),
// Project Structure
APP = {
SRC: {
BASE: "./src/main/webapp/js",
DEST: "./src/main/webapp/dist",
GLOBS: [
"**/*.js"
],
FILTER: () => APP.SRC.GLOBS.map(glob => path.join(APP.SRC.BASE, glob))
},
TESTS: {
BASE: "./src/test/js",
DEST: "./src/test/dist",
GLOBS: [
"**/*.js"
],
FILTER: () => APP.TESTS.GLOBS.map(glob => path.join(APP.TESTS.BASE, glob))
},
DEPS: {
BASE: "./node_modules",
DEST: "./src/main/webapp/lib",
GLOBS: Object.keys (PACKAGE_JSON.dependencies).map(dep => dep + "/**/*"),
FILTER: () => APP.DEPS.GLOBS.map (glob => path.join(APP.DEPS.BASE, glob))
}
};
gulp.task ('default', ['build:deps', 'build:src']);
// Link the dependencies to the lib directory instead of requiring a copy.
gulp.task ('build:deps', function () {
return gulp.src(APP.DEPS.FILTER(), { base: APP.DEPS.BASE})
.pipe(symlink(APP.DEPS.DEST, {}));
});
// Just an example. Babel would go here.
gulp.task ('build:src', function () {
return gulp.src(APP.SRC.FILTER(), { base: APP.SRC.BASE})
.pipe(gulp.dest(APP.SRC.DEST));
});
// Clean project
gulp.task('build:clean', function () {
return gulp.src(Object.keys(APP).map(key => APP[key]["DEST"]).filter(Boolean))
.pipe(clean());
});
/**
* Create a special symlink stream processor which will
* use junctions instead of dir on Windows. As the 'dir' symlink
* on Windows is all but impossible to create as a User with Admin rights.
*/
function symlink(outFolder, opt) {
function linkFile(file, enc, cb) {
var srcPath = file.path;
var symType = file.isDirectory() ? ((process.platform === 'win32') ? 'junction' : 'dir') : 'file';
prepareWrite(outFolder, file, opt, function(err, writePath) {
if (err) {
return cb(err);
}
fs.symlink(srcPath, writePath, symType, function(err) {
if (err && err.code !== 'EEXIST') {
return cb(err);
}
cb(null, file);
});
});
}
var stream = through2.obj(opt, linkFile);
stream.resume();
return stream;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment