На срещата на върха имах възможност да говоря с Guy Podjarny за това защо бих преминал от nsp към snyk. За мен най-голямото разочарование от използването на nsp беше „списъкът с изключения“, който трябваше да поддържам във всички мои проекти, които използваха nsp. На теория уязвимостите не се освобождават, докато няма налични корекции за уязвимостта; на практика уязвимите пакети все още присъстват като преходни зависимости в продължение на седмици, дори ако използвате Greenkeeper, за да поддържате зависимостите си актуални. Файлът nsprc изглеждаше като списък с уязвимости, които нападателите биха могли да използват, за да пробият моите приложения и библиотеки, и сякаш покривах случаи на уязвимост, която можех да коригирам, защото имаше такава, която не можех. Snyk се доставя с команда protect, която да се изпълнява като част от жизнения цикъл на пакета на npm, за да приложи пачове, които поддържат вашия модул защитен, докато корекцията си проправя път през вашето затваряне на зависимост.

Съветникът за Snyk върши страхотна работа за преоборудване на вашите съществуващи npm скриптове, за да изпълняват задачите си в правилната част от жизнения цикъл на npm

"scripts": {
    "prepublish": "npm run snyk-protect; gulp prepublish",
    "test": "snyk test && gulp",
    "clean": "gulp clean",
    "snyk-protect": "snyk protect"
  },

Въпреки това може да искате Snyk да се изпълнява като част от вашия работен процес за разработка, като използвате gulp, вместо да използвате директно npm. Екосистемата на nsp беше лесната интеграция с gulp с gulp-nsp.

const nsp = require('gulp-nsp');
const path = require('path');
gulp.task('nsp', (cb) => {
  nsp({package: path.join(__dirname, 'package.json')}, cb);
});

Оказва се обаче, че snyk има страхотен програмен API, базиран на обещания, който не изглежда документиран, доколкото мога да преценя.

const snyk = require('snyk');
snyk.test('.').then((data) => { 
  if (data.vulnerabilities.length) { 
    console.error(data.vulnerabilities);
    throw new Error(`Snyk found ${data.vulnerabilities.length} vulnernabilities`);
  }
});

Което прави доста лесно да напишете проста задача за преглъщане, която използва snyk и се проваля при изграждането, когато се открият уязвимости

const snyk = require('snyk');
const gulp = require('gulp');
gulp.task('snyk', function () {
 return snyk.test('.').then((data) => {
  this.emit('error', new Error(`Snyk found vulnerabilities ${JSON.stringify(data.vulnerabilities)}`));
 });
});

Което улеснява консолидирането в една доста проста задача чрез актуализиране на съществуващата test задача (като `gulp.task(‘test’, [‘xo’, ‘ava’, ‘coveralls’, ‘snyk’]);`

"scripts": {
    "prepublish": "npm run snyk-protect; gulp prepublish",
    "test": "gulp test",
    "clean": "gulp clean",
    "snyk-protect": "snyk protect"
  },

Но все още има стъпката snyk, която не се изпълнява при предварително публикуване. Когато инсталирате нови зависимости, трябва да коригирате затварянето на зависимостта; prepublish се изпълнява, когато инсталирате вашите зависимости (а не когато вашият модул е ​​инсталиран като зависимост, като кукичките на жизнения цикъл на инсталиране). Ако използвате вашия prepublish скрипт като ваш общ build скрипт, може да не искате разработчиците да изпълняват snyk protect на всяка компилация, но ако сте ги разделили и искате предварителното публикуване да работи по същия начин локално, както на CI, може да искате да стартирате защити в част от gulp prepublish. Изглежда, че няма метод за защита на програмния API, но вместо това можете да използвате child_process.exec

const gulp = require('gulp');
const cp = require('child_process');
gulp.task('protect', function(cb) {
 cp.exec('./node_modules/.bin/snyk protect', (err, data) => {
  gutil.log(data);
  cb();
 });
})

Но това е нещо, което трябва да запомните и ако трябва да инсталирате gulp-util, вие вече добавяте импортиране и зависимост, така че ако предпочитате, можете вместо това да вземете gulp-snyk от npm

const gulp = require('gulp');
const snyk = require('gulp-snyk');
gulp.task('protect', function(cb) {
 return snyk({command: 'protect', debug: true}, cb);
});
gulp.task('test', function (cb) {
 return snyk({command: 'test', debug: true}, cb);
});
gulp.task('prepublish', ['protect']);

И тогава вашият package.json е просто преминаване към вашия gulp файл

"scripts": {
    "prepublish": "gulp prepublish",
    "test": "gulp test"
},

Приятно хакване!