-
Notifications
You must be signed in to change notification settings - Fork 1k
/
gulpfile.js
204 lines (170 loc) · 5.71 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
const connect = require('connect');
const cssnano = require('cssnano');
const fs = require('fs-extra');
const frontMatter = require('front-matter');
const globby = require('globby');
const gulp = require('gulp');
const he = require('he');
const hljs = require('highlight.js');
const htmlMinifier = require('html-minifier');
const MarkdownIt = require('markdown-it');
const nunjucks = require('nunjucks');
const path = require('path');
const postcss = require('postcss');
const atImport = require('postcss-import');
const postcssPresetEnv = require('postcss-preset-env');
const serveStatic = require('serve-static');
const sh = require('shelljs');
const {argv} = require('yargs');
const isProd = () => process.env.NODE_ENV == 'production';
/**
* The output directory for all the built files.
*/
const DEST = './solved-by-flexbox';
/**
* The base public path of the site.
*/
const PUBLIC_PATH = path.join('/', DEST, '/');
nunjucks.configure('templates', {autoescape: false, noCache: true});
/**
* Renders markdown content as HTML with syntax highlighted code blocks.
* @param {string} content A markdown string.
* @return {string} The rendered HTML.
*/
const renderMarkdown = (content) => {
const md = new MarkdownIt({
html: true,
typographer: true,
highlight: (code, lang) => {
code = lang ? hljs.highlight(lang, code).value :
// Since we're not using highlight.js here, we need to
// espace the html, but we have to unescape first in order
// to avoid double escaping.
he.escape(he.unescape(code));
return code;
},
});
return md.render(content);
};
gulp.task('pages', async () => {
const baseData = await fs.readJSON('./config.json');
const overrides = {
baseUrl: PUBLIC_PATH,
env: process.env.NODE_ENV || 'development'
};
const site = Object.assign({demos: []}, baseData, overrides);
const processContent = async (pagePath) => {
const slug = path.basename(pagePath, path.extname(pagePath));
const permalink = site.baseUrl +
(slug === 'index' ? '' : 'demos/' + slug + '/');
const fileContents = await fs.readFile(pagePath, 'utf-8');
const {body, attributes} = frontMatter(fileContents);
const data = {
site,
page: {
content: body,
slug,
permalink,
...attributes,
},
};
if (path.extname(pagePath) == '.md') {
data.page.content = renderMarkdown(data.page.content);
}
data.page.content = nunjucks.renderString(data.page.content, data);
return data;
}
const renderPage = async (data) => {
let html = nunjucks.render(data.page.template, data);
if (process.env.NODE_ENV === 'production') {
html = htmlMinifier.minify(html, {
removeComments: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
minifyJS: true,
minifyCSS: true,
});
};
const outputPath = path.join(data.page.permalink.slice(1), 'index.html');
await fs.outputFile(outputPath, html);
};
const demoPaths = await globby('./demos/**/*');
for (const demoPath of demoPaths) {
const data = await processContent(demoPath);
// Add the page data to the site demos.
site.demos.push(data.page);
await renderPage(data);
};
const pagePaths = await globby('*.html');
for (const pagePath of pagePaths) {
const data = await processContent(pagePath);
await renderPage(data);
};
});
gulp.task('images', () => {
return gulp.src('./assets/images/**/*')
.pipe(gulp.dest(path.join(DEST, 'images')));
});
gulp.task('css', async () => {
const src = './assets/css/main.css';
const css = await fs.readFile(src, 'utf-8');
const plugins = [
atImport(),
postcssPresetEnv({
stage: 0,
browsers: '> 1%, last 2 versions, Safari > 5, ie > 9, Firefox ESR',
}),
];
if (process.env.NODE_ENV === 'production') {
plugins.push(cssnano({
preset: ['default', {discardComments: {removeAll: true}}],
}));
}
const result = await postcss(plugins).process(css, {from: src});
await fs.outputFile(path.join(DEST, path.basename(src)), result.css);
});
gulp.task('javascript', async () => {
await sh.exec('rollup -c');
});
gulp.task('default', gulp.parallel('css', 'images', 'javascript', 'pages'));
gulp.task('serve', gulp.series('default', () => {
let port = argv.port || argv.p || 4000;
connect().use(serveStatic('./')).listen(port);
gulp.watch('./assets/css/**/*.css', gulp.series('css'));
gulp.watch('./assets/images/*', gulp.series('images'));
gulp.watch('./assets/main.js', gulp.series('javascript'));
gulp.watch(['*.html', './demos/*', './templates/*'], gulp.series('pages'));
}));
gulp.task('deploy', gulp.series('default', (done) => {
if (process.env.NODE_ENV != 'production') {
throw new Error('Deploying requires NODE_ENV to be set to production');
}
const repoUrl = 'git@github.com:philipwalton/solved-by-flexbox.git';
// Create a temporary directory and
// checkout the existing gh-pages branch.
sh.rm('-rf', '_tmp');
sh.mkdir('_tmp');
sh.cd('_tmp');
sh.exec('git init');
sh.exec('git remote add origin ' + repoUrl);
sh.exec('git pull origin gh-pages');
// Delete all the existing files and add
// the new ones from the build directory.
sh.rm('-rf', './*');
sh.cp('-rf', path.join('..', DEST, '/*'), './');
sh.exec('git add -A');
// Commit and push the changes to
// the gh-pages branch.
sh.exec('git commit -m "Deploy site"');
sh.exec('git branch -m gh-pages');
sh.exec('git push origin gh-pages');
// Clean up.
sh.cd('..');
sh.rm('-rf', '_tmp');
sh.rm('-rf', DEST);
done();
}));