New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@joinbox/build-task

Package Overview
Dependencies
Maintainers
2
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@joinbox/build-task - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

3

package.json
{
"name": "@joinbox/build-task",
"version": "0.1.0",
"version": "0.2.0",
"description": "Re-usable gulp 4/webpack build tasks for Joinbox projects",

@@ -42,2 +42,3 @@ "main": "./src/BuildTask.js",

"del": "^3.0.0",
"eslint-loader": "^2.0.0",
"event-emitter": "^0.3.5",

@@ -44,0 +45,0 @@ "glob": "^7.1.2",

@@ -16,255 +16,255 @@ const colors = require('colors');

constructor() {
constructor() {
// Simple event emitter that can be called when changes happen; serve tasks listens for
// events and updates on changes
this.changeWatcher = new EventEmitter();
// Simple event emitter that can be called when changes happen; serve tasks listens for
// events and updates on changes
this.changeWatcher = new EventEmitter();
// All tasks; key: name, value: function
this.tasks = new Map();
// All dev subtasks, will run after cleanup in default task
this.devTasks = [];
// All watch subtasks; will run after dev tasks in default task
this.watchTasks = [];
// All prod subtasks: Will be called in parallel after clean in 'prod' task
this.prodTasks = [];
// All tasks; key: name, value: function
this.tasks = new Map();
// All dev subtasks, will run after cleanup in default task
this.devTasks = [];
// All watch subtasks; will run after dev tasks in default task
this.watchTasks = [];
// All prod subtasks: Will be called in parallel after clean in 'prod' task
this.prodTasks = [];
// Configuratio needed to create tasks
this.config = defaultConfig;
}
// Configuratio needed to create tasks
this.config = defaultConfig;
}
/**
* Updates the certain parts of the configuration.
* @param {string} path Path to the property (of this.config) to modify.
* @param {*} value Value to set property to
*/
setConfig(path, value) {
const property = getProperty(this.config, path);
property.reference.entity[property.reference.property] = value;
}
/**
* Updates the certain parts of the configuration.
* @param {string} path Path to the property (of this.config) to modify.
* @param {*} value Value to set property to
*/
setConfig(path, value) {
const property = getProperty(this.config, path);
property.reference.entity[property.reference.property] = value;
}
/**
* Main methiod: Creates and returns the built tasks
* @return {[type]} [description]
*/
createTasks() {
/**
* Main methiod: Creates and returns the built tasks
* @return {[type]} [description]
*/
createTasks() {
this.createScriptTasks();
this.createStyleTasks();
this.createTemplateTasks();
this.createServeTask();
this.createCleanTask();
this.createScriptTasks();
this.createStyleTasks();
this.createTemplateTasks();
this.createServeTask();
this.createCleanTask();
// Create default task (clears destination, calls all dev then watch tasks)
this.tasks.set('default', gulp.series(
// Remove dest folder
this.tasks.get('clean'),
// Execute all dev tasks (initial dev)
gulp.parallel(this.devTasks),
// Execute all watch tasks and serve (don't use serial here, all tasks will run
// indefinitely)
gulp.parallel(this.watchTasks.concat(() => {
this.config.server ? this.tasks.get('serve')() : null;
})),
));
// Create default task (clears destination, calls all dev then watch tasks)
this.tasks.set('default', gulp.series(
// Remove dest folder
this.tasks.get('clean'),
// Execute all dev tasks (initial dev)
gulp.parallel(this.devTasks),
// Execute all watch tasks and serve (don't use serial here, all tasks will run
// indefinitely)
gulp.parallel(this.watchTasks.concat(() => {
this.config.server ? this.tasks.get('serve')() : null;
})),
));
// Create prod task
this.tasks.set('prod', gulp.series(
this.tasks.get('clean'),
(done) => {
console.log(colors.cyan('BuildTask: Execute %d prod tasks'), this.prodTasks.length);
done();
},
gulp.parallel(this.prodTasks),
));
// Create prod task
this.tasks.set('prod', gulp.series(
this.tasks.get('clean'),
(done) => {
console.log(colors.cyan('BuildTask: Execute %d prod tasks'), this.prodTasks.length);
done();
},
gulp.parallel(this.prodTasks),
));
// Convert this.tasks (Map) into an object which will then be returned
const returnObject = {};
this.tasks.forEach((task, name) => {
returnObject[name] = task;
});
// Convert this.tasks (Map) into an object which will then be returned
const returnObject = {};
this.tasks.forEach((task, name) => {
returnObject[name] = task;
});
console.log(colors.cyan('BuildTask: Tasks are %s'),
Object.keys(returnObject).join(', '));
console.log(colors.cyan('BuildTask: Tasks are %s'),
Object.keys(returnObject).join(', '));
return returnObject;
return returnObject;
}
}
/**
* Just emits a change on this.changeWatcher. this.changeWatcher is where our browsersync server
* listens to and reloads when a 'change' event. Hook your watch tasks in here.
*/
emitChange() {
console.log(colors.cyan('BuildTask: Emit change'));
this.changeWatcher.emit('change');
return Promise.resolve();
}
/**
* Just emits a change on this.changeWatcher. this.changeWatcher is where our browsersync server
* listens to and reloads when a 'change' event. Hook your watch tasks in here.
*/
emitChange() {
console.log(colors.cyan('BuildTask: Emit change'));
this.changeWatcher.emit('change');
return Promise.resolve();
}
/**
* Removes the destination folder
* @private
*/
createCleanTask() {
this.tasks.set('clean',
createCleanTasks(path.join(this.config.paths.base, this.config.paths.destination)));
}
/**
* Removes the destination folder
* @private
*/
createCleanTask() {
this.tasks.set('clean',
createCleanTasks(path.join(this.config.paths.base, this.config.paths.destination)));
}
/**
* @private
*/
createScriptTasks() {
/**
* @private
*/
createScriptTasks() {
if (!this.config.scripts) return;
if (!this.config.scripts) return;
console.log(colors.cyan('BuildTask: Create script tasks'));
const jsDev = createScriptTasks(this.config.scripts, this.config.paths,
this.config.supportedBrowsers);
const jsProd = createScriptTasks(this.config.scripts, this.config.paths,
this.config.supportedBrowsers, 'production');
const fullJsDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.scripts.paths, 'destination')),
jsDev,
this.emitChange.bind(this),
);
console.log(colors.cyan('BuildTask: Create script tasks'));
const jsDev = createScriptTasks(this.config.scripts, this.config.paths,
this.config.supportedBrowsers);
const jsProd = createScriptTasks(this.config.scripts, this.config.paths,
this.config.supportedBrowsers, 'production');
const fullJsDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.scripts.paths, 'destination')),
jsDev,
this.emitChange.bind(this),
);
let watchPath = this.getWatchPath(this.config.scripts);
console.log(colors.cyan('BuildTask: Watch JS files on %s'), watchPath);
const jsWatch = () => gulp.watch(watchPath, gulp.series(jsDev, this.emitChange.bind(this)));
this.tasks.set('jsDev', fullJsDev);
this.tasks.set('jsWatch', jsWatch);
this.tasks.set('jsProd', jsProd);
this.tasks.set('js', gulp.series(fullJsDev, jsWatch));
let watchPath = this.getWatchPath(this.config.scripts);
console.log(colors.cyan('BuildTask: Watch JS files on %s'), watchPath);
const jsWatch = () => gulp.watch(watchPath, gulp.series(jsDev, this.emitChange.bind(this)));
this.tasks.set('jsDev', fullJsDev);
this.tasks.set('jsWatch', jsWatch);
this.tasks.set('jsProd', jsProd);
this.tasks.set('js', gulp.series(fullJsDev, jsWatch));
this.watchTasks.push(jsWatch);
this.devTasks.push(jsDev);
this.prodTasks.push(jsProd);
this.watchTasks.push(jsWatch);
this.devTasks.push(jsDev);
this.prodTasks.push(jsProd);
console.log(colors.cyan('BuildTask: Script tasks created'));
console.log(colors.cyan('BuildTask: Script tasks created'));
}
}
/**
* Create all style tasks
* @private
*/
createStyleTasks() {
/**
* Create all style tasks
* @private
*/
createStyleTasks() {
if (!this.config.styles) return;
if (!this.config.styles) return;
console.log(colors.cyan('BuildTask: Create style tasks'));
const cssDev = createStyleTasks(this.config.styles, this.config.paths,
this.config.supportedBrowsers);
const cssProd = createStyleTasks(this.config.styles, this.config.paths,
this.config.supportedBrowsers, 'production');
const fullCssDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.styles.paths, 'destination')),
cssDev,
this.emitChange.bind(this),
);
console.log(colors.cyan('BuildTask: Create style tasks'));
const cssDev = createStyleTasks(this.config.styles, this.config.paths,
this.config.supportedBrowsers);
const cssProd = createStyleTasks(this.config.styles, this.config.paths,
this.config.supportedBrowsers, 'production');
const fullCssDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.styles.paths, 'destination')),
cssDev,
this.emitChange.bind(this),
);
let watchPath = this.getWatchPath(this.config.styles);
console.log(colors.cyan('BuildTask: Watch CSS files on %s'), watchPath);
const cssWatch = () => gulp.watch(watchPath, gulp.series(
cssDev,
this.emitChange.bind(this),
));
this.tasks.set('cssDev', fullCssDev);
this.tasks.set('cssWatch', cssWatch);
this.tasks.set('cssProd', cssProd);
this.tasks.set('css', gulp.series(fullCssDev, cssWatch));
let watchPath = this.getWatchPath(this.config.styles);
console.log(colors.cyan('BuildTask: Watch CSS files on %s'), watchPath);
const cssWatch = () => gulp.watch(watchPath, gulp.series(
cssDev,
this.emitChange.bind(this),
));
this.tasks.set('cssDev', fullCssDev);
this.tasks.set('cssWatch', cssWatch);
this.tasks.set('cssProd', cssProd);
this.tasks.set('css', gulp.series(fullCssDev, cssWatch));
this.watchTasks.push(cssWatch);
this.devTasks.push(cssDev);
this.prodTasks.push(cssProd);
this.watchTasks.push(cssWatch);
this.devTasks.push(cssDev);
this.prodTasks.push(cssProd);
console.log(colors.cyan('BuildTask: Style tasks created'));
console.log(colors.cyan('BuildTask: Style tasks created'));
}
}
/**
* Small helper: Returns a watch path for a config passed in
* @private
*/
getWatchPath(typeConfig) {
let watchPath = getPath(this.config.paths, typeConfig.paths);
watchPath = path.join(watchPath, typeConfig.paths.watch);
return watchPath;
}
/**
* Small helper: Returns a watch path for a config passed in
* @private
*/
getWatchPath(typeConfig) {
let watchPath = getPath(this.config.paths, typeConfig.paths);
watchPath = path.join(watchPath, typeConfig.paths.watch);
return watchPath;
}
/**
* @private
*/
createTemplateTasks() {
/**
* @private
*/
createTemplateTasks() {
if (!this.config.templates) return;
if (!this.config.templates) return;
console.log(colors.cyan('BuildTask: Create template tasks'));
console.log(colors.cyan('BuildTask: Create template tasks'));
// For html files, there's no difference between dev and prod (yet) – we might use
// minification one day.
const htmlDev = createTemplateTasks(this.config.templates, this.config.paths);
const htmlProd = createTemplateTasks(this.config.templates, this.config.paths,
'production');
// For html files, there's no difference between dev and prod (yet) – we might use
// minification one day.
const htmlDev = createTemplateTasks(this.config.templates, this.config.paths);
const htmlProd = createTemplateTasks(this.config.templates, this.config.paths,
'production');
const fullHtmlDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.templates.paths, 'destination')),
htmlDev,
this.emitChange.bind(this),
);
const fullHtmlDev = gulp.series(
createCleanTasks(getPath(this.config.paths, this.config.templates.paths, 'destination')),
htmlDev,
this.emitChange.bind(this),
);
let watchPath = this.getWatchPath(this.config.templates);
console.log(colors.cyan('BuildTask: Watch HTML files on %s'), watchPath);
const htmlWatch = () => gulp.watch(watchPath, gulp.series(
htmlDev,
this.emitChange.bind(this),
));
this.tasks.set('htmlDev', fullHtmlDev);
this.tasks.set('htmlWatch', htmlWatch);
this.tasks.set('htmlProd', htmlProd);
this.tasks.set('html', gulp.series(fullHtmlDev, htmlWatch));
let watchPath = this.getWatchPath(this.config.templates);
console.log(colors.cyan('BuildTask: Watch HTML files on %s'), watchPath);
const htmlWatch = () => gulp.watch(watchPath, gulp.series(
htmlDev,
this.emitChange.bind(this),
));
this.tasks.set('htmlDev', fullHtmlDev);
this.tasks.set('htmlWatch', htmlWatch);
this.tasks.set('htmlProd', htmlProd);
this.tasks.set('html', gulp.series(fullHtmlDev, htmlWatch));
this.watchTasks.push(htmlWatch);
this.devTasks.push(htmlDev);
this.prodTasks.push(htmlProd);
this.watchTasks.push(htmlWatch);
this.devTasks.push(htmlDev);
this.prodTasks.push(htmlProd);
console.log(colors.cyan('BuildTask: Template tasks created'));
console.log(colors.cyan('BuildTask: Template tasks created'));
}
}
/**
* @private
*/
createServeTask() {
if (!this.config.server) return;
/**
* @private
*/
createServeTask() {
if (!this.config.server) return;
console.log(colors.cyan('BuildTask: Create serve task'));
const serve = createBrowserSync(
this.config.server,
this.config.paths,
this.changeWatcher,
);
this.tasks.set('serve', serve);
console.log(colors.cyan('BuildTask: Serve task created'));
console.log(colors.cyan('BuildTask: Create serve task'));
const serve = createBrowserSync(
this.config.server,
this.config.paths,
this.changeWatcher,
);
this.tasks.set('serve', serve);
console.log(colors.cyan('BuildTask: Serve task created'));
}
}
};

@@ -8,4 +8,4 @@ const path = require('path');

* Create server
* @param {object} serverConfig Config for server
* @param {paths} paths Config for paths
* @param {object} serverConfig Config for server
* @param {paths} paths Config for paths
* @param {EventEmitter} watcher Event emitter that emits events on change (js, css, html files

@@ -15,19 +15,19 @@ * etc.)

module.exports = function createBrowserSync(serverConfig, paths, watcher) {
// Path where files are served from
const htmlDestPath = getPath(paths, serverConfig.paths);
// Path to watch – reload browserSync on changes
const watchPath = path.join(htmlDestPath, serverConfig.paths.watch);
// Path where files are served from
const htmlDestPath = getPath(paths, serverConfig.paths);
// Path to watch – reload browserSync on changes
const watchPath = path.join(htmlDestPath, serverConfig.paths.watch);
console.log(colors.blue('Serve: Serving from %s, watching %s'), htmlDestPath, watchPath);
console.log(colors.blue('Serve: Serving from %s, watching %s'), htmlDestPath, watchPath);
return function() {
browserSync.init({
server: path.join(paths.base, paths.destination),
startPath: serverConfig.paths.start,
});
return function() {
browserSync.init({
server: path.join(paths.base, paths.destination),
startPath: serverConfig.paths.start,
});
watcher.on('change', browserSync.reload);
};
watcher.on('change', browserSync.reload);
};
};

@@ -5,7 +5,7 @@ const colors = require('colors');

module.exports = function(path) {
console.log(colors.grey('Remove %s'), path);
return (done) => del(path).then((paths) => {
console.log(colors.grey('Removed paths %s'), paths.join('\n'));
done();
});
console.log(colors.grey('Remove %s'), path);
return (done) => del(path).then((paths) => {
console.log(colors.grey('Removed paths %s'), paths.join('\n'));
done();
});
};

@@ -13,40 +13,47 @@ // gulp-notifier has write method which is needed but not documented – don't use it

/**
* Basic JS task for dev and production mode
* Don't use webpack-stream in combination with gulp because:
* - directories are not preserved, see https://github.com/shama/webpack-stream/issues/62
* - it's overly complex (error handling, sourcemaps, named() for multiple files …)
* @return {object} Exported gup tasks
*/
return function(done) {
/**
* Basic JS task for dev and production mode
* Don't use webpack-stream in combination with gulp because:
* - directories are not preserved, see https://github.com/shama/webpack-stream/issues/62
* - it's overly complex (error handling, sourcemaps, named() for multiple files …)
* @return {object} Exported gup tasks
*/
return function(done) {
const webpackConfig = getWebpackConfig(scriptConfig, pathConfig, browsers, environment);
//console.log('Scripts: webpack config is %o', webpackConfig);
const webpackConfig = getWebpackConfig(scriptConfig, pathConfig, browsers, environment);
//console.log('Scripts: webpack config is %o', webpackConfig);
webpack(webpackConfig).run((err, stats) => {
webpack(webpackConfig).run((err, stats) => {
let notificationOptions;
// Basic error
if (err) notificationOptions = getNotificationOptions('Scripts', err);
// Error when compiling a single or multiple files
else if (stats.compilation.errors && stats.compilation.errors.length) {
notificationOptions = getNotificationOptions('Scripts',
new Error(stats.compilation.errors));
console.error(stats.compilation.errors);
}
// All fine
else {
const assets = Object.keys(stats.compilation.assets).join(', ');
notificationOptions = getNotificationOptions('Scripts', assets);
console.log(colors.yellow('Webpack: Result is %s'), stats.toString());
}
//console.log(stats.compilation);
notifier.notify(notificationOptions);
done();
});
};
let notificationOptions;
// Basic error
if (err) notificationOptions = getNotificationOptions('Scripts', err);
// Error when compiling a single or multiple files (webpack errors)
else if (stats.compilation.errors && stats.compilation.errors.length) {
notificationOptions = getNotificationOptions('Scripts',
new Error(stats.compilation.errors));
console.error(colors.red(stats.compilation.errors));
}
// Warnings (e.g. from esLint)
else if (stats.compilation.warnings && stats.compilation.warnings.length) {
const err = new Error(`Warning: ${ stats.compilation.warnings.join(', ')}`);
err.name = 'LintError';
notificationOptions = getNotificationOptions('Scripts', err);
}
// All fine
else {
const assets = Object.keys(stats.compilation.assets).join(', ');
notificationOptions = getNotificationOptions('Scripts', assets);
console.log(colors.yellow('Webpack: Result is %s'), stats.toString());
}
//console.log(stats.compilation);
notifier.notify(notificationOptions);
done();
});
};
};

@@ -19,63 +19,63 @@ const gulp = require('gulp');

module.exports = function createStyleTasks(
styleConfig,
paths,
browsers,
environment = 'development'
styleConfig,
paths,
browsers,
environment = 'development'
) {
const sassOptions = environment === 'development' ? { outputStyle: 'expanded'} :
{ outputStyle: 'compressed' };
const sourcePath = getPath(paths, styleConfig.paths);
const sources = styleConfig.paths.entries.map((entry) => path.join(sourcePath, entry));
const destinationPath = getPath(paths, styleConfig.paths, 'destination');
console.log(colors.green('Styles: Sources are %s, destination is %s'), sources.join(', '),
destinationPath);
const sassOptions = environment === 'development' ? { outputStyle: 'expanded'} :
{ outputStyle: 'compressed' };
const sourcePath = getPath(paths, styleConfig.paths);
const sources = styleConfig.paths.entries.map((entry) => path.join(sourcePath, entry));
const destinationPath = getPath(paths, styleConfig.paths, 'destination');
console.log(colors.green('Styles: Sources are %s, destination is %s'), sources.join(', '),
destinationPath);
return function() {
return function() {
let hasErrored = false;
let hasErrored = false;
return gulp.src(sources)
.pipe(plumber({
errorHandler: () => (err) => notifier.notify(getNotificationOptions('Styles', err))
}))
.pipe(print())
.pipe(sourcemaps.init())
return gulp.src(sources)
.pipe(plumber({
errorHandler: () => (err) => notifier.notify(getNotificationOptions('Styles', err))
}))
.pipe(print())
.pipe(sourcemaps.init())
.pipe(sassGlob())
.pipe(
sass(sassOptions)
// We need to handle Sass compilation errors specifically, they won't be cought
// by plumber. Don't use arrow function as scope must be preserved for logError
.on('error', function(err) {
sass.logError.call(this, err);
notifier.notify(getNotificationOptions('Styles', err));
hasErrored = true;
})
)
.pipe(sassGlob())
.pipe(
sass(sassOptions)
// We need to handle Sass compilation errors specifically, they won't be cought
// by plumber. Don't use arrow function as scope must be preserved for logError
.on('error', function(err) {
sass.logError.call(this, err);
notifier.notify(getNotificationOptions('Styles', err));
hasErrored = true;
})
)
.pipe(postcss([
autoprefixer({
browsers: browsers
}),
pxtorem({
propWhiteList: [],
rootValue: 16
}),
calc
]))
.pipe(postcss([
autoprefixer({
browsers: browsers
}),
pxtorem({
propWhiteList: [],
rootValue: 16
}),
calc
]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(destinationPath))
//.pipe(browsersync.reload({stream: true}))
//.pipe(browsersyncPatternlab.reload({stream: true}))
.on('end', () => {
if (hasErrored) return;
notifier.notify(getNotificationOptions('Styles'));
});
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(destinationPath))
//.pipe(browsersync.reload({stream: true}))
//.pipe(browsersyncPatternlab.reload({stream: true}))
.on('end', () => {
if (hasErrored) return;
notifier.notify(getNotificationOptions('Styles'));
});
};
};
};

@@ -11,25 +11,25 @@ const gulp = require('gulp');

const sources = getPath(paths, templateConfig.paths);
const destination = getPath(paths, templateConfig.paths, 'destination');
const entries = templateConfig.paths.entries.map((entry) => {
return path.join(sources, entry);
});
const sources = getPath(paths, templateConfig.paths);
const destination = getPath(paths, templateConfig.paths, 'destination');
const entries = templateConfig.paths.entries.map((entry) => {
return path.join(sources, entry);
});
console.log(colors.blue('createTemplateTasks: Entries are %s, destination %s'), entries,
destination);
console.log(colors.blue('createTemplateTasks: Entries are %s, destination %s'), entries,
destination);
return function() {
return gulp.src(entries)
.pipe(print())
// This is dangerous/unexpected, consult case 1 on https://github.com/robrich/gulp-if
// Make sure gulpif comes straight before gulp.dest!
.pipe(gulpif(environment === 'production', htmlmin({
// Options: https://github.com/kangax/html-minifier
collapseWhitespace: true,
conservativeCollapse: true,
preserveLineBreaks: true,
})))
.pipe(gulp.dest(destination));
};
return function() {
return gulp.src(entries)
.pipe(print())
// This is dangerous/unexpected, consult case 1 on https://github.com/robrich/gulp-if
// Make sure gulpif comes straight before gulp.dest!
.pipe(gulpif(environment === 'production', htmlmin({
// Options: https://github.com/kangax/html-minifier
collapseWhitespace: true,
conservativeCollapse: true,
preserveLineBreaks: true,
})))
.pipe(gulp.dest(destination));
};
};
const defaults = {
// For sub-paths, use arrays!
paths: {
base: 'www',
source: 'src',
destination: 'dest',
public: '', // Directory to serve files from
},
// Use false to not expose scripts task
scripts: {
// use ['default'] or ['react'] (not both, react includes default)
technologies: ['default'],
paths: {
source: 'js',
watch: '**/*.js?(x)',
destination: 'js',
entries: ['main.js'],
output: '[name].js',
}
},
// Use false to not expose styles task
styles: {
paths: {
source: 'css',
destination: 'css',
watch: '**/*.scss',
entries: ['main.scss'],
}
},
// Use false to not template scripts
templates: {
paths: {
source: 'html',
watch: '**/*.html',
destination: 'html',
entries: ['**/*.html'],
},
},
production: {
bustCache: false, // TBD
},
// False to not add it to tasks
server: {
paths: {
source: 'html',
watch: '**/*.html',
start: 'html' // Where to point to
}
},
// Browser applies to CSS prefixing and JS babel compilation, see
// https://github.com/browserslist/browserslist#queries
supportedBrowsers: [
'last 2 versions',
],
// For sub-paths, use arrays!
paths: {
base: 'www',
source: 'src',
destination: 'dest',
public: '', // Directory to serve files from
},
// Use false to not expose scripts task
scripts: {
// use ['default'] or ['react'] (not both, react includes default)
technologies: ['default'],
paths: {
source: 'js',
watch: '**/*.js?(x)',
destination: 'js',
entries: ['main.js'],
output: '[name].js',
}
},
// Use false to not expose styles task
styles: {
paths: {
source: 'css',
destination: 'css',
watch: '**/*.scss',
entries: ['main.scss'],
}
},
// Use false to not template scripts
templates: {
paths: {
source: 'html',
watch: '**/*.html',
destination: 'html',
entries: ['**/*.html'],
},
},
production: {
bustCache: false, // TBD
},
// False to not add it to tasks
server: {
paths: {
source: 'html',
watch: '**/*.html',
start: 'html' // Where to point to
}
},
// Browser applies to CSS prefixing and JS babel compilation, see
// https://github.com/browserslist/browserslist#queries
supportedBrowsers: [
'last 2 versions',
],
};
module.exports = defaults;

@@ -5,23 +5,33 @@ const colors = require('colors');

* Generates the config for notifications
* @param {string} type 'Scripts' or 'styles' (or others)
* @param {string|object} error Error object or a string; if it's an error object, an error
* @param {string} type 'Scripts' or 'styles' (or others)
* @param {string|object} error Error object or a string; if it's an error object, an error
* message will be displayed
*/
module.exports = function(type, content) {
console.log(colors.grey('getNotifyOptions for %s, error %o'), type, content instanceof Error);
const title = content instanceof Error ? `${ type } failed 😈` : `${ type } done 🚀`;
const text = content instanceof Error ?
content.message :
`${ type } successfully compiled${ content ? ': ' + content : '' }.`;
console.log(colors.grey(`getNotifyOptions: title ${ title }, text ${ text }.`));
return {
// Only one notification per task, not per stream
onLast: true, //error ? false : true,
title: title,
message: text,
};
console.log(colors.grey('getNotifyOptions for %s, error %o'), type, content instanceof Error);
let title, text;
if (content instanceof Error && content.name === 'LintError') {
title = `${ type } did not pass lint 🚑`;
text = content.message;
}
else if (content instanceof Error) {
title = `${ type } failed 😈`;
text = content.message;
}
else {
title = `${ type } done 🚀`;
text = `${ type } successfully compiled${ content ? ': ' + content : '' }.`;
}
console.log(colors.grey(`getNotifyOptions: title ${ title }, text ${ text }.`));
return {
// Only one notification per task, not per stream
onLast: true, //error ? false : true,
title: title,
message: text,
};
};

@@ -13,10 +13,10 @@ const path = require('path');

module.exports = function(paths, typeConfig, type = 'source') {
//console.log(colors.grey('Get paths for %o %o and type %s'), paths, typeConfig, type);
if (paths.base === undefined) throw new Error(`getSources: base property missing on paths
${ JSON.stringify(paths) }`);
if (paths[type] === undefined) throw new Error(`getSources: ${ type } property missing on
paths ${ JSON.stringify(paths) }`);
if (!typeConfig[type] === undefined) throw new Error(`getSources: ${ type } property missing on
type config ${ JSON.stringify(typeConfig) }`);
return path.join(process.cwd(), paths.base, paths[type], typeConfig[type]);
//console.log(colors.grey('Get paths for %o %o and type %s'), paths, typeConfig, type);
if (paths.base === undefined) throw new Error(`getSources: base property missing on paths
${ JSON.stringify(paths) }`);
if (paths[type] === undefined) throw new Error(`getSources: ${ type } property missing on
paths ${ JSON.stringify(paths) }`);
if (!typeConfig[type] === undefined) throw new Error(`getSources: ${ type } property missing on
type config ${ JSON.stringify(typeConfig) }`);
return path.join(process.cwd(), paths.base, paths[type], typeConfig[type]);
};

@@ -11,19 +11,19 @@ /**

module.exports = function(object, path) {
const slices = path.split('.');
let currentObject = object;
let parentObject; // Defaults to undefined
slices.reduce((prev, slice) => {
if (!currentObject[slice]) throw new Error(`getProperty: Property for path ${ prev } not
found in object ${ JSON.stringify(object) }, full path is ${ path }.`);
parentObject = currentObject;
currentObject = currentObject[slice];
return prev + '.' + slice;
}, '');
return {
reference: {
entity: parentObject,
property: slices.pop(),
},
value: currentObject,
};
const slices = path.split('.');
let currentObject = object;
let parentObject; // Defaults to undefined
slices.reduce((prev, slice) => {
if (!currentObject[slice]) throw new Error(`getProperty: Property for path ${ prev } not
found in object ${ JSON.stringify(object) }, full path is ${ path }.`);
parentObject = currentObject;
currentObject = currentObject[slice];
return prev + '.' + slice;
}, '');
return {
reference: {
entity: parentObject,
property: slices.pop(),
},
value: currentObject,
};
};

@@ -5,47 +5,47 @@ const test = require('ava');

function setupData() {
const object1 = {
name: 'joinbox',
address: {
street: 'brückfeld'
},
phones: {
mobile: [
'1234',
'4321',
],
},
};
return { object1 };
const object1 = {
name: 'joinbox',
address: {
street: 'brückfeld'
},
phones: {
mobile: [
'1234',
'4321',
],
},
};
return { object1 };
}
test('throws on wrong path', (t) => {
const { object1 } = setupData();
t.throws(() => getProperty(object1, 'name.subvalue'), /for path/);
const { object1 } = setupData();
t.throws(() => getProperty(object1, 'name.subvalue'), /for path/);
});
test('finds valid object paths', (t) => {
const { object1 } = setupData();
t.deepEqual(getProperty(object1, 'name'), {
value: 'joinbox', reference: {
property: 'name',
entity: object1,
}
});
t.deepEqual(getProperty(object1, 'address.street'), {
value: 'brückfeld',
reference: {
entity: object1.address,
property: 'street'
}
});
const { object1 } = setupData();
t.deepEqual(getProperty(object1, 'name'), {
value: 'joinbox', reference: {
property: 'name',
entity: object1,
}
});
t.deepEqual(getProperty(object1, 'address.street'), {
value: 'brückfeld',
reference: {
entity: object1.address,
property: 'street'
}
});
});
test('works with arrays', (t) => {
const { object1 } = setupData();
t.deepEqual(getProperty(object1, 'phones.mobile.1'), {
value: '4321', reference: {
property: '1',
entity: object1.phones.mobile,
}
});
const { object1 } = setupData();
t.deepEqual(getProperty(object1, 'phones.mobile.1'), {
value: '4321', reference: {
property: '1',
entity: object1.phones.mobile,
}
});
});

@@ -17,43 +17,43 @@ const glob = require('glob');

console.log(colors.yellow('Webpack: Create config; jsConfig is \n%s\npathConfig is \n%s'),
JSON.stringify(jsConfig, null, 2), JSON.stringify(pathConfig, null, 2));
console.log(colors.yellow('Webpack: Create config; jsConfig is \n%s\npathConfig is \n%s'),
JSON.stringify(jsConfig, null, 2), JSON.stringify(pathConfig, null, 2));
// Get paths; make sure you're running gulp from the directory where your gulp file lies
const baseSourcePath = getPath(pathConfig, jsConfig.paths);
const baseDestinationPath = getPath(pathConfig, jsConfig.paths, 'destination');
console.log(colors.yellow('Webpack: baseSourcePath is %s, baseDestinationPath is %s'),
baseSourcePath, baseDestinationPath);
// Get paths; make sure you're running gulp from the directory where your gulp file lies
const baseSourcePath = getPath(pathConfig, jsConfig.paths);
const baseDestinationPath = getPath(pathConfig, jsConfig.paths, 'destination');
console.log(colors.yellow('Webpack: baseSourcePath is %s, baseDestinationPath is %s'),
baseSourcePath, baseDestinationPath);
// Allow globs as entry points – and also (and especially) arrays of globs. Webpack does not
// support it, do it manually: https://github.com/webpack/webpack/issues/370
const entries = jsConfig.paths.entries
// 1. Resolve all array's items globs to files
.reduce((prev, source) => {
const sourceWithPath = path.join(baseSourcePath, source);
console.log(colors.yellow('Webpack: Get files for %s from glob %s'), source,
sourceWithPath);
return [...prev, ...glob.sync(sourceWithPath)];
}, [])
// 2. Make all paths absolute if it is not already
.map((item) => path.isAbsolute(item) ? item : path.join(baseSourcePath, item))
// 3. Now make an object out of our files (if we pass an array as entry point, webpack will
// create just one file, main.js). The object's key is the relative path from
// baseSourcePath
.reduce((prev, item) => {
// Relative path is the difference from baseSourcePath to item and therefore
// also the difference where we want to store the file relative to baseDestinationPath
const relativePath = path.relative(baseSourcePath, item);
// Remove the extension which will be added when saving – if we don't we'll have two
// extensions
const extension = path.extname(relativePath);
const relativePathWithoutExtension = relativePath.substr(0, relativePath.length -
extension.length);
return {...prev, ...{ [relativePathWithoutExtension]: item} };
}, {});
// Allow globs as entry points – and also (and especially) arrays of globs. Webpack does not
// support it, do it manually: https://github.com/webpack/webpack/issues/370
const entries = jsConfig.paths.entries
// 1. Resolve all array's items globs to files
.reduce((prev, source) => {
const sourceWithPath = path.join(baseSourcePath, source);
console.log(colors.yellow('Webpack: Get files for %s from glob %s'), source,
sourceWithPath);
return [...prev, ...glob.sync(sourceWithPath)];
}, [])
// 2. Make all paths absolute if it is not already
.map((item) => path.isAbsolute(item) ? item : path.join(baseSourcePath, item))
// 3. Now make an object out of our files (if we pass an array as entry point, webpack will
// create just one file, main.js). The object's key is the relative path from
// baseSourcePath
.reduce((prev, item) => {
// Relative path is the difference from baseSourcePath to item and therefore
// also the difference where we want to store the file relative to baseDestinationPath
const relativePath = path.relative(baseSourcePath, item);
// Remove the extension which will be added when saving – if we don't we'll have two
// extensions
const extension = path.extname(relativePath);
const relativePathWithoutExtension = relativePath.substr(0, relativePath.length -
extension.length);
return {...prev, ...{ [relativePathWithoutExtension]: item} };
}, {});
console.log(colors.yellow('Webpack: Sources are %s'), Object.values(entries).join(', '));
console.log(colors.yellow('Webpack: Sources are %s'), Object.values(entries).join(', '));

@@ -64,17 +64,17 @@

const webpackConfig = {
mode: mode,
entry: entries,
output: {
filename: jsConfig.paths.output,
// Don't use __dirname as it resolves to the node's base directory (where
// package.json lies)
path: baseDestinationPath,
},
devtool: 'source-map',
module: {
rules: getWebpackRules(jsConfig.technologies, browsers)
}
};
const webpackConfig = {
mode: mode,
entry: entries,
output: {
filename: jsConfig.paths.output,
// Don't use __dirname as it resolves to the node's base directory (where
// package.json lies)
path: baseDestinationPath,
},
devtool: 'source-map',
module: {
rules: getWebpackRules(jsConfig.technologies, browsers),
},
};

@@ -85,7 +85,7 @@

console.log(colors.yellow('Webpack: Final config is \n%s'),
JSON.stringify(webpackConfig, null, 2));
console.log(colors.yellow('Webpack: Final config is \n%s'),
JSON.stringify(webpackConfig, null, 2));
return webpackConfig;
return webpackConfig;
};

@@ -5,28 +5,26 @@ const colors = require('colors');

const rules = [];
const rules = [];
// Default tech
if (technologies.includes('default')) {
console.log(colors.yellow('Webpack: Use default technologies'));
rules.push(getDefaultRule(browsers));
}
// React
if (technologies.includes('react')) {
console.log(colors.yellow('Webpack: Use react'));
// Clone default rule before modifying it
const reactRule = getDefaultRule(browsers);
reactRule.test = /.*\.jsx?$/,
reactRule.use.options.presets.push('@babel/react');
rules.push(reactRule);
}
rules.push(getEslintRule());
console.log(colors.yellow('WebpackRules: There are %d rules: %s'), rules.length,
JSON.stringify(rules, null, 2));
return rules;
// Default tech
if (technologies.includes('default')) {
console.log(colors.yellow('Webpack: Use default technologies'));
rules.push(getDefaultRule(browsers));
}
// React
if (technologies.includes('react')) {
console.log(colors.yellow('Webpack: Use react'));
// Clone default rule before modifying it
const reactRule = getDefaultRule(browsers);
reactRule.test = /.*\.jsx?$/,
reactRule.use.options.presets.push('@babel/react');
rules.push(reactRule);
}
console.log(colors.yellow('WebpackRules: There are %d rules'), rules.length);
return rules;
};

@@ -41,19 +39,38 @@

function getDefaultRule(browsers) {
return {
test: /.*\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
targets: browsers,
},
],
],
babelrc: false,
cacheDirectory: true,
},
}
};
return {
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
targets: browsers,
},
],
],
babelrc: false,
cacheDirectory: true,
},
}
};
}
function getEslintRule() {
return {
test: /\.jsx?$/,
use: {
loader: 'eslint-loader',
// Location of .eslintrc: See webpack config,
// https://github.com/webpack-contrib/eslint-loader/commit/
// cf48c8077ad63e689c56600f0cf2a81107fc8b56
options: {
configFile: '../node_modules/@joinbox/eslint-config-joinbox/.eslintrc',
enforce: 'pre',
emitWarning: true,
exclude: /node_modules/,
}
}
}
}
import number from './module';
const obj = { number };
console.log({ ...obj, spread: true });
//console.log('change');
console.log({ ...obj, spread: true }); //eslint-disable-line
// console.log('change');
export default function() {
return 4;
}
return 4;
}
const a = 3;
function multiply(factor) {
return factor**factor;
return factor**factor;
}
console.log(multiply(a));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc