Skip to content

Instantly share code, notes, and snippets.

@albell
Created February 3, 2017 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save albell/47543b636c5aef7b0eed7d4943cc7ea4 to your computer and use it in GitHub Desktop.
Save albell/47543b636c5aef7b0eed7d4943cc7ea4 to your computer and use it in GitHub Desktop.
/* eslint no-param-reassign: ["off"] */
/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true,
"optionalDependencies": false, "peerDependencies": false}] */
/**
* Assemble has first-class support for vinyl-fs, so any gulp plugin can be used
* directly in the assemble pipeline.
*/
const assemble = require('assemble');
const watch = require('base-watch');
const browserSync = require('browser-sync').create();
const email = require('gulp-email');
const extReplace = require('gulp-ext-replace');
const inlineCss = require('gulp-inline-css');
const modify = require('gulp-modify');
const plumber = require('gulp-plumber');
const sass = require('gulp-sass');
const gulpStyleLint = require('gulp-stylelint');
const app = assemble();
app.use(watch());
/**
* ASSET PATHS
*
* Useful for changing build environments. When relocating files for a back-end
* integration everything should be reconfigurable from here. Set the
* image asset path string directly in partial/assetpath.hbs
*/
const PATH = {
src: './email-src/',
css: './email-src/css/',
emails: './email-src/emails/',
img: './email-src/img/',
layout: './email-src/layout/',
partial: './email-src/partial/',
dist: './email-dist/',
};
app.task('serve', () => {
browserSync.init({
server: {
baseDir: PATH.dist,
index: 'message.html',
},
// Watching.
// files: [
// `${PATH.src}**/*.hbs`,
// `${PATH.css}**/*.scss`,
// ],
});
});
/**
* SCSS Linting.
*/
app.task('scss-lint', (() =>
app.src(`${PATH.css}**/*.scss`)
.pipe(gulpStyleLint({
reporters: [
{ formatter: 'string', console: true },
],
}))
));
/**
* Compile SCSS to CSS, and save the resulting file as a partial for
* subsequent insertion into the <style> tag.
*/
app.task('scss', (() =>
app.src(`${PATH.css}global-style.scss`)
// .pipe(plumber())
.pipe(sass().on('error', function (err) {
console.error(err.message);
// Display error in the browser.
browserSync.notify(err.message, 3000);
// Prevent assemble from catching the error and exiting watch process.
this.emit('end');
}))
.pipe(extReplace('.hbs'))
.pipe(modify({
fileModifier(file, contents) {
console.log(file);
console.log(contents);
file.stat.mtime = new Date();
return contents;
},
}))
.pipe(app.dest(PATH.partial))
));
/**
* Assemble emails from the Handlebars templates.
* (Image assets should be uploaded separately to AWS. Get S3 creds from Haven CTO.
* After FTP upload, set 'Read: World' permissions for all uploaded files.)
*/
app.task('build', () => {
// Don't move these, the file collections generated by the globs are static,
// and need to be freshly declared at the start of the task, or the task
// will use old file collections generated from before any tasks were run.
app.layouts(`${PATH.layout}*.hbs`);
app.partials(`${PATH.partial}*.hbs`);
return app.src(`${PATH.emails}/*.hbs`)
.pipe(app.renderFile()) // Render using default engine (hbs).
.pipe(inlineCss({
preserveMediaQueries: true,
removeStyleTags: true,
}))
.pipe(extReplace('.html'))
.pipe(modify({
fileModifier(file, contents) {
file.stat.mtime = new Date();
return contents;
},
}))
.pipe(app.dest(PATH.dist));
});
// Configure the Mailgun option to email the design to your inbox, or Litmus.
// https://www.npmjs.com/package/gulp-mailgun
app.task('send', (() =>
app.src(`${PATH.dist}*.html`)
.pipe(email({
user: '###########', // Mailgun API key here
url: 'https://api.mailgun.net/v2/sandbox4825.mailgun.org/messages',
form: {
from: 'postmaster@sandboxa721bde9e410419ca0b85cba1170056d.mailgun.org',
to: 'recipient@example.com',
// Unique date prevents email clients from combining tests into a
// single thread.
subject: `Test email subject ${new Date()}`,
},
}))
));
/**
* Default task, when 'assemble' is run without options.
* Use Gulp-4-style .series() method here, otherwise the tasks will be run
* by default in parallel, which would inline the old compiled CSS from the
* previous build.
*/
app.task('default', app.series('scss-lint', 'scss', 'build'));
app.task('watch', app.parallel('serve', app.series('default', () => {
// Basically just rebuild everything any time anything in the src changes.
app.watch([`${PATH.css}**/*.scss`, `${PATH.src}**/*.hbs`], () => {
console.log('something changed');
});
})));
module.exports = app;
{
"name": "email-starter-boilerplate",
"description": "Assemble-based workflow for building templatized emails",
"version": "0.2.0",
"license": "MIT",
"dependencies": {
"assemble": "^0.20.0",
"browser-sync": "^2.18.7",
"eslint": "^3.14.1",
"eslint-config-airbnb": "^14.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^3.0.2",
"eslint-plugin-react": "^6.9.0",
"gulp-autoprefixer": "^3.1.1",
"gulp-email": "0.0.7",
"gulp-ext-replace": "^0.3.0",
"gulp-inline-css": "^3.1.0",
"gulp-modify": "^0.1.1",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^3.1.0"
},
"devDependencies": {
"base-watch": "^0.1.3",
"gulp-stylelint": "^3.7.0",
"stylelint-config-standard": "^16.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment