Repository navigation
Expand file tree
/
Copy pathgulpfile.js
More file actions
152 lines (133 loc) · 4.3 KB
/
Copy pathgulpfile.js
File metadata and controls
152 lines (133 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
const gulp = require('gulp');
const plugins = require('gulp-load-plugins');
const browser = require('browser-sync');
const rimraf = require('rimraf');
const panini = require('panini/gulp');
const yargs = require('yargs');
const lazypipe = require('lazypipe');
const inky = require('inky');
const fs = require('fs');
const siphon = require('siphon-media-query');
const path = require('path');
const merge = require('merge-stream');
const beep = require('beepbeep');
const colors = require('colors');
const gulpSass = require('gulp-dart-sass');
const glob = require('glob');
const $ = plugins();
// Look for the --production flag
const PRODUCTION = !!yargs.argv.production;
const EMAIL = yargs.argv.to;
let paniniInstance;
// Build the "dist" folder by running all of the below tasks
gulp.task('build', gulp.series(clean, partials, pages, sass, inline, checkPanini));
// Build emails, run the server, and watch for file changes
gulp.task('default', gulp.series('build', server, watch));
// Delete the "dist" folder
// This happens every time a build starts
function clean(done) {
rimraf('dist', done);
}
// Compile layouts, pages, and partials into flat HTML files
// Then parse using Inky templates
function pages() {
const stream = panini('src').pipe(inky()).pipe(gulp.dest('dist'));
paniniInstance = stream._panini;
return stream;
}
// Copy localized partials folders (e.g. src/partials/en -> dist/en/partials)
function partials() {
const partialsDir = path.join('src', 'partials');
const items = fs.readdirSync(partialsDir);
const streams = items
.filter(name => fs.statSync(path.join(partialsDir, name)).isDirectory())
.map(lang => {
const fragDir = path.join(partialsDir, lang, 'fragments');
if (fs.existsSync(fragDir) && fs.statSync(fragDir).isDirectory()) {
return gulp.src(path.join(fragDir, '/**/*')).pipe(gulp.dest(path.join('dist', lang, 'partials')));
}
return null;
})
.filter(Boolean);
return streams.length ? merge.apply(null, streams) : null;
}
// Compile Sass into CSS
function sass() {
return gulp
.src('src/assets/scss/app.scss')
.pipe($.if(!PRODUCTION, $.sourcemaps.init()))
.pipe(
gulpSass({
includePaths: ['node_modules/foundation-emails/scss'],
}).on('error', gulpSass.logError),
)
.pipe(
$.if(
PRODUCTION,
$.uncss({
html: ['dist/**/*.html'],
}),
),
)
.pipe($.if(!PRODUCTION, $.sourcemaps.write()))
.pipe(gulp.dest('dist/css'));
}
// Inline CSS and minify HTML
function inline() {
return gulp
.src('dist/**/*.html')
.pipe($.if(PRODUCTION, inliner('dist/css/app.css')))
.pipe(gulp.dest('dist'));
}
// Fail the build if panini rendered any error pages (it swallows per-page
// render exceptions and substitutes an error page instead of failing).
function checkPanini(done) {
glob('dist/**/*.html', (err, files) => {
if (err) return done(err);
let broken;
try {
broken = files.filter(f => fs.readFileSync(f, 'utf8').includes('<!-- __PANINI_ERROR__ -->'));
} catch (e) {
return done(e);
}
if (broken.length) {
return done(new Error(`Panini rendered ${broken.length} error page(s):\n${broken.join('\n')}`));
}
done();
});
}
// Start a server with LiveReload to preview the site in
function server(done) {
browser.init({
server: 'dist',
});
done();
}
// Watch for file changes
function watch() {
gulp
.watch(['src/pages/**/*.html', 'src/layouts/**/*', 'src/partials/**/*'])
.on('all', gulp.series(partials, pages, inline, browser.reload));
gulp
.watch(['../scss/**/*.scss', 'src/assets/scss/**/*.scss'])
.on('all', gulp.series(sass, pages, inline, browser.reload));
}
// Inlines CSS into HTML, adds media query CSS into the <style> tag of the email, and compresses the HTML
function inliner(css) {
var css = fs.readFileSync(css).toString();
var mqCss = siphon(css);
var pipe = lazypipe()
.pipe($.inlineCss, {
applyStyleTags: true,
removeStyleTags: true,
preserveMediaQueries: true,
removeLinkTags: true,
})
.pipe($.replace, '<!-- <style> -->', `<style>${mqCss}</style>`)
.pipe($.replace, '<link rel="stylesheet" type="text/css" href="css/app.css">', '')
.pipe($.htmlmin, {
collapseWhitespace: true,
minifyCSS: true,
});
return pipe();
}