EmailThis / extension-boilerplate

⚡️ A template for building cross browser extensions for Chrome, Opera & Firefox.
https://www.emailthis.me/open-source/extension-boilerplate
MIT License
3.28k stars 370 forks source link

Upgrade Dependencies to fix vulnerabilities #36

Open GenieTim opened 5 years ago

GenieTim commented 5 years ago

Dear maintainer

Thank you for this repository. In this pull request, I propose upgrading Babel to version 7 and gulp to version 4. The required changes should all be present. Reasons for the upgrades include

Best regards

piotrkochan commented 5 years ago

My dist/ zip contains only styles/popup.css file on this code.

GenieTim commented 5 years ago

True, insofar as that it is not necessarily a vulnerability for the users of the extensions as the dependencies are rather dev-use only. I have to admit that I did not take a closer look at the vulnerabilities reported – I could imagine e.g. a vulnerability in babel could lead to security issues in the compiled JavaScript, therefore affecting the end user. But yeah, just speculating here

piotrkochan commented 5 years ago

This is what I finally created based on Your PR, unfortunately I have a problem with zip, zip package does not contains scritps/ folder and I don't know why. If I remove clean task from the build then all files are present.


import browserify from 'browserify';
import merge from 'merge-stream';
import fs from 'fs';
import gulp from 'gulp';
import gulpif from 'gulp-if';
import preprocessify from 'preprocessify';
import buffer from 'vinyl-buffer';
import source from 'vinyl-source-stream';

const $ = require('gulp-load-plugins')();

const production = process.env.NODE_ENV === 'production';
const target = process.env.TARGET || 'chrome';
const environment = process.env.NODE_ENV || 'development';

var generic = JSON.parse(fs.readFileSync(`./config/${environment}.json`));
var specific = JSON.parse(fs.readFileSync(`./config/${target}.json`));
var context = Object.assign({}, generic, specific);

var defaultManifest = {
  dev: {
    'background':
      {
        'scripts': [
          'scripts/livereload.js',
          'scripts/icon-changer.js'
        ]
      }
  },
  firefox: { 'applications': { 'gecko': { 'id': 'my-app-id@mozilla.org' } } }
};

function styles() {
  return gulp.src('src/styles/**/*.scss')
    .pipe($.plumber())
    .pipe(
      $.sass
        .sync({ outputStyle: 'expanded', precision: 10, includePaths: ['.'] })
        .on('error', $.sass.logError)
    )
    .pipe(gulp.dest(`./build/${target}/styles/`));
}

function manifest() {
  return gulp.src('./manifest.json')
    .pipe(gulpif(!production, $.mergeJson({
      fileName: 'manifest.json',
      jsonSpace: ' '.repeat(4),
      endObj: defaultManifest.dev
    })))
    .pipe(gulpif(target === 'firefox', $.mergeJson({
      fileName: 'manifest.json',
      jsonSpace: ' '.repeat(4),
      endObj: defaultManifest.firefox
    })))

    .pipe(gulp.dest(`./build/${target}`))
}

exports.manifest = manifest;

function pipe(src, ...transforms) {
  return transforms.reduce((stream, transform) => {
    const isDest = typeof transform === 'string';
    return stream.pipe(isDest ? gulp.dest(transform) : transform)
  }, gulp.src(src, { allowEmpty: true }))
}

function zip() {
  return gulp.src(`build/${target}/**/*`)
    .pipe($.zip(`${target}.zip`))
    .pipe(gulp.dest('./dist'))
}

function buildJS(target) {
  let files = [
    'contentscript.js', 'icon-changer.js', 'popup.js',
  ];

  if (!production) {
    files.push('livereload.js');
  }

  let tasks = files.map(file => {
    return browserify({ entries: 'src/scripts/' + file, debug: true })
      .transform('babelify', { presets: ['@babel/preset-env'] })
      .transform(preprocessify, { includeExtensions: ['.js'], context: context })
      .bundle()
      .pipe(source(file))
      .pipe(buffer())
      .pipe(gulpif(!production, $.sourcemaps.init({ loadMaps: true })))
      .pipe(gulpif(!production, $.sourcemaps.write('./')))
      .pipe(gulpif(production, $.uglify({ 'mangle': false, 'output': { 'ascii_only': true } })))
      .pipe(gulp.dest(`./build/${target}/scripts`));
  });

  return merge(tasks)
}

function js(done) {
  buildJS(target);
  done()
}

function clean() {
  return pipe(`./build/${target}`, $.clean())
}

function watch() {
  $.livereload.listen();
  gulp.watch('./src/**/*', gulp.series('build', function (done) {
    $.livereload.reload();
    done();
  }))

  // gulp.watch('./src/**/*', gulp.series('build'))
}

function files() {
  return merge(
    pipe('./src/icons/**/*', `./build/${target}/icons`),
    pipe(['./src/_locales/**/*'], `./build/${target}/_locales`),
    pipe([`./src/images/${target}/**/*`], `./build/${target}/images`),
    pipe(['./src/images/shared/**/*'], `./build/${target}/images`),
    pipe(['./src/**/*.html'], `./build/${target}`))
}

exports.clean = clean;
exports.assets = gulp.series(styles, js);
exports.build = gulp.series(clean, exports.assets, manifest, files);
exports.watch = gulp.series(exports.build, watch);
exports.dist = gulp.series(exports.build, zip);

exports.default = exports.build;
GenieTim commented 5 years ago

I am sorry, @piotrkochan, I may not understand your inquiry. The code you posted is not mine, nor the one in this PR (see gulpfile.babel.js). The error you mention looks like you have a typo somewhere: scritps instead of scripts, but I do not understand when and where this error is thrown. Would you please mind open an issue if you have problems with the code in this repo, instead of commenting here, especially if unrelated to this PR.