-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgulpfile.js
401 lines (342 loc) · 9.49 KB
/
gulpfile.js
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/**
*
* 21sieben website gulpfile.js
*
*/
var gulp = require('gulp');
var gulpLoadPlugins = require('gulp-load-plugins');
var browserSync = require('browser-sync').create();
var cp = require('child_process');
var moduleImporter = require('sass-module-importer');
var runSequence = require('run-sequence');
var dotenv = require('dotenv');
var autoprefixer = require('autoprefixer');
var postCssSyntaxScss = require('postcss-scss');
var stylelint = require('stylelint');
var cssnano = require('cssnano');
var reporter = require('postcss-reporter');
var notifier = require('node-notifier');
var path = require('path');
var fs = require('fs');
var browserify = require('browserify');
var envify = require('envify');
var babelify = require('babelify');
var buffer = require('vinyl-buffer');
var critical = require('critical');
// Setup & Configuration
// ==============================
// Read .env file and store its contents in process.env variable
dotenv.config();
// NODE_ENV, should default to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var messages = {
eleventyBuild: '<span style="color: grey">Running:</span> $ eleventy build'
};
// store all gulp plugins in $
const $ = gulpLoadPlugins();
// Configuration
var config = {};
// base
config.siteName = '21sieben';
config.proxyDomain = process.env.BROWSERSYNC_PROXY_DOMAIN || '21sieben.test';
// destination directories
config.dest = '_site/';
config.destJS = config.dest + 'js';
config.destCSS = config.dest + 'css';
config.destSVG = config.dest + 'images/svg';
config.destIMG = config.dest + 'images/layout';
// destination directories (root)
config.destJSRoot = 'js';
config.destCSSRoot = 'css';
config.destSVGRoot = 'images/svg';
config.destIMGRoot = 'images/layout';
// entry files
config.entries = {
scss: '_scss/main.scss',
js: '_js/main.js',
}
// globs
config.globs = {
scss: '_scss/**/*.scss',
js: '_js/**/*.js',
svg: '_images/svg/*.svg',
img: '_images/layout/**/*',
eleventy: ['_data/*', '*.html', '.eleventy*', 'static', '_layouts/*.html', '_includes/**/*', '_skills/*',]
};
// Environment handling tasks
// ==============================
gulp.task('set-dev-node-env', function() {
return process.env.NODE_ENV = 'development';
});
gulp.task('set-prod-node-env', function() {
return process.env.NODE_ENV = 'production';
});
// Notification icons
// ==============================
/**
* Checks to see if a file exists.
*/
function fileExists(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
}
// Get success icon
const iconPathSuccess = path.join(__dirname, 'gulp/icon--success.png');
const iconSuccess = fileExists(iconPathSuccess) ? iconPathSuccess : null;
// Get error icon
const iconPathError = path.join(__dirname, 'gulp/icon--error.png');
const iconError = fileExists(iconPathError) ? iconPathError : null;
// Plumber error handler
// ==============================
function plumberErrorHandler(err) {
// notify by console log
$.util.log($.util.colors.white.bgRed("Build error:"), err.message);
// notify by notification
notifier.notify({
title: config.siteName,
message: 'Build error! "' + err.message + '"',
icon: iconError
});
this.emit('end');
}
// ELEVENTY TASKS
// ==============================
/**
* Build the Eleventy Site
*/
gulp.task('eleventy-build', function(done) {
browserSync.notify(messages.eleventyBuild);
return cp.spawn('npx', ['eleventy'], {
stdio: 'inherit'
})
.on('close', done);
});
/**
* Rebuild Eleventy & do page reload
*/
gulp.task('eleventy-rebuild', ['eleventy-build'], function() {
browserSync.reload();
});
/**
* Wait for eleventy-build, then launch the Server
*/
gulp.task('browser-sync', function() {
browserSync.init({
host: config.proxyDomain,
logSnippet: false,
});
});
// STYLES TASK
// Compiles files from _scss into /_site/css and /css
// Also does the usual autoprefixer/minify/linting stuff
// ==============================
var postCSSPreProcessors = [
stylelint(),
reporter({
clearReportedMessages: true,
})
];
var postCSSPostProcessors = [
autoprefixer(),
cssnano({
preset: 'default',
}),
];
gulp.task('sass', function() {
return gulp.src(config.entries.scss)
.pipe($.plumber({
errorHandler: plumberErrorHandler
}))
.pipe($.if(process.env.NODE_ENV === 'development', $.sourcemaps.init()))
.pipe($.postcss(postCSSPreProcessors, {
syntax: postCssSyntaxScss
}))
.pipe($.sass({
importer: moduleImporter(),
outputStyle: ':compact',
precision: 10
}))
.pipe($.postcss(postCSSPostProcessors))
.pipe($.rename({
suffix: '.min'
}))
.pipe($.size({
showFiles: true
}))
.pipe($.if(process.env.NODE_ENV === 'development', $.sourcemaps.write('./')))
.pipe(gulp.dest(config.destCSS))
.pipe(gulp.dest(config.destCSSRoot))
.pipe(browserSync.reload({
stream: true
}));
});
// SCRIPTS TASK: Babelify, bundle, lint and minify JavaScript.
//
// Note:
// * ES6 is supported
// * that includes ES6 imports via browserify + babelify.
// ==============================
// TODO: Upgrade to babel 7
// TODO: Check babel-polyfill + preset-env
gulp.task('scripts', ['eslint'], function() {
// log NODE_ENV
$.util.log('Building scripts with NODE_ENV:', process.env.NODE_ENV);
return gulp.src(config.entries.js, {
read: false
})
.pipe($.plumber({
errorHandler: plumberErrorHandler
}))
.pipe($.tap(function(file) {
// browserify inside gulp-tap, so plumbering still works.
file.contents = browserify({
entries: [file.path],
debug: process.env.NODE_ENV === 'development'
})
.transform(envify, {
_: 'purge',
global: true
})
.transform(babelify)
.bundle();
}))
.pipe(buffer()) // converts bundled stream, so it can be further processed
.pipe($.rename({
suffix: '.min'
}))
.pipe($.if(process.env.NODE_ENV === 'development', $.sourcemaps.init({
loadMaps: true
})))
.pipe($.uglify())
.pipe($.size({
showFiles: true
}))
.pipe($.if(process.env.NODE_ENV === 'development', $.sourcemaps.write('./')))
.pipe(gulp.dest(config.destJS))
.pipe(gulp.dest(config.destJSRoot))
.pipe(browserSync.reload({
stream: true
}));
});
// ESLINT TASK: Lint JavaScript
// ==============================
gulp.task('eslint', function() {
return gulp.src([config.globs.js])
.pipe($.eslint())
.pipe($.eslint.format())
});
// SVG TASK: Create SVG spritemap
// ==============================
gulp.task('svg', function() {
var svgSpriteConfig = {
log: 'info',
svg: {
namespaceClassnames: false
},
mode: {
symbol: {
dest: '.',
sprite: 'sprite.svg'
}
}
};
return gulp.src(config.globs.svg)
.pipe($.plumber({
errorHandler: plumberErrorHandler
}))
.pipe($.svgSprite(svgSpriteConfig))
.pipe(gulp.dest(config.destSVG))
.pipe(gulp.dest(config.destSVGRoot));
});
/**
* Rebuild SVGs & do page reload
*/
gulp.task('svg-rebuild', ['svg'], function() {
browserSync.reload();
});
// IMG TASK: Simply copy images
// ==============================
gulp.task('img', function() {
return gulp.src(config.globs.img)
.pipe($.plumber({
errorHandler: plumberErrorHandler
}))
.pipe(gulp.dest(config.destIMG))
.pipe(gulp.dest(config.destIMGRoot));
});
/**
* Rebuild images & do page reload
*/
gulp.task('img-rebuild', ['img'], function() {
browserSync.reload();
});
// WATCH TASK: Watch files for changes
// ==============================
gulp.task('watch', function() {
// watch all .scss files, recompile SASS
$.watch(config.globs.scss, function(vinyl) {
$.util.log($.util.colors.underline('\nFile changed: ' + vinyl.relative));
gulp.start('sass');
});
// watch all script files, recompile scripts
$.watch(config.globs.js, function(vinyl) {
$.util.log($.util.colors.underline('\nFile changed: ' + vinyl.relative));
gulp.start('scripts');
});
// watch all svg files, recompile SVG spritemap
$.watch(config.globs.svg, function(vinyl) {
$.util.log($.util.colors.underline('\nFile changed: ' + vinyl.relative));
gulp.start('svg-rebuild');
});
// watch all Eleventy files, run Eleventy & reload BrowserSync
$.watch(config.globs.eleventy, function(vinyl) {
$.util.log($.util.colors.underline('\nFile changed: ' + vinyl.relative));
gulp.start('eleventy-rebuild');
});
// watch all image files, recopy images
$.watch(config.globs.img, function(vinyl) {
$.util.log($.util.colors.underline('\nFile changed: ' + vinyl.relative));
gulp.start('img-rebuild');
});
});
// CRITICAL TASK: Build critical CSS
// ==============================
gulp.task('critical', function () {
critical.generate({
inline: true,
dest: 'critical/',
src: 'http://' + config.proxyDomain,
minify: true,
dimensions: [
{
width: 320,
height: 480,
},
{
width: 1200,
height: 900,
}
]
});
});
// DEFAULT TASK: Build files and serve browsersync
// ==============================
gulp.task('default', callback =>
runSequence(
['sass', 'scripts', 'svg', 'img', 'eleventy-build'],
'browser-sync',
'watch',
callback
)
);
// PRODUCTION TASK: Set NODE_ENV to production and build files
// ==============================
gulp.task('production', callback =>
runSequence(
['set-prod-node-env', 'sass', 'scripts', 'svg', 'img', 'eleventy-build'],
callback
)
);