UNPKG

9.68 kBJavaScriptView Raw
1const gulp = require("gulp");
2const del = require("del");
3const sass = require("gulp-sass");
4
5let defaultRollupOptions = null;
6const getDefaultRollupOptions = () => {
7 if (!defaultRollupOptions) {
8 const babel = require("rollup-plugin-babel");
9 const nodeResolve = require("rollup-plugin-node-resolve");
10 const commonJs = require("rollup-plugin-commonjs");
11
12 defaultRollupOptions = [{
13 "plugins": [
14 babel({
15 babelrc: false,
16 comments: false,
17 presets: [['@babel/preset-env', {
18 targets: {
19 "ie": "11"
20 },
21 loose: true,
22 modules: false
23 }]],
24 runtimeHelpers: true,
25 plugins: [
26 ["@babel/transform-runtime"]
27 ]
28 }),
29 commonJs(),
30 nodeResolve()
31 ]
32 }, {
33 "format": "iife"
34 }]
35 }
36 return defaultRollupOptions;
37}
38
39
40
41
42/**
43 * Generates exports for a gulpfile based on our common business patterns
44 * @param {*} options
45 */
46const createGulpfile = (options) => {
47 const {
48 include = {}
49 } = options;
50
51
52 let tasks = {}; // Tasks that may be called individually
53
54 let cleanTask = null; // Before all other build tasks
55 let parallelBuildTasks = []; // One-time build of project
56
57 let watchTasks = []; // Watch tasks in parallel
58
59 let deployTask = null;
60 let serveTask = null;
61
62
63 /**
64 * Setup clean tasks
65 */
66 if (include.clean) {
67 const cleanParams = include.clean;
68 const clean = () => del(cleanParams);
69
70 cleanTask = clean;
71 tasks.clean = clean;
72 // Clean doesn't have a watch task associated with it
73 }
74
75 /**
76 * Setup copy tasks
77 */
78 if (include.copy) {
79 const copyDefsParam = include.copy;
80 const result = createCopyAll(copyDefsParam);
81
82 tasks = {...tasks, ...result.tasks};
83 parallelBuildTasks = [...parallelBuildTasks, ...result.parallelBuildTasks];
84 watchTasks = [...watchTasks, ...result.watchTasks];
85 }
86
87 /**
88 * Setup Sass tasks
89 */
90 if (include.scss) {
91 const {src, dest, watchSrc, options} = include.scss;
92 const {scss, scssWatch} = createSass(src, dest, watchSrc);
93
94 tasks.scss = scss;
95 parallelBuildTasks.push(scss);
96 watchTasks.push(scssWatch);
97 }
98
99 /**
100 * Setup TypeScript tasks
101 */
102 if (include.ts) {
103 const typescript = require("gulp-typescript");
104
105 const {src, dest, tsconfig, clean} = include.ts;
106 const {ts, tsWatch} = createTypeScript(src, dest, tsconfig);
107
108 let rollupTask;
109 let declarationsTask;
110 let cleanTask;
111
112 const declarationOptions = include.ts.declarations;
113
114 if (declarationOptions) {
115 const {src, dest} = declarationOptions;
116
117 const declarations = () => gulp.src(src)
118 .pipe(gulp.dest(dest));
119
120 const declarationsWatch = () => gulp.watch(src, declarations);
121
122 tasks.declarations = declarations;
123 declarationsTask = declarations;
124 watchTasks.push(declarationsWatch);
125 }
126
127 let rollupOptions = include.ts.rollup; // To deal with variable/constant scope and same-named variables
128
129 if (rollupOptions) {
130 const rollupPipe = require("gulp-better-rollup");
131
132 let single = rollupOptions.src && rollupOptions.dest;
133
134 if (single) {
135 const {src, dest, options} = rollupOptions;
136
137 const rollup = () => gulp.src(src)
138 .pipe(rollupPipe(...(options || getDefaultRollupOptions())))
139 .pipe(gulp.dest(dest));
140
141 const rollupWatch = () => gulp.watch(src, rollup);
142
143 tasks.rollup = rollup;
144 rollupTask = rollup;
145 watchTasks.push(rollupWatch);
146 } else {
147 let rollupTasks = [];
148
149 for (const key of Object.keys(rollupOptions)) {
150 const {src, dest, options} = rollupOptions[key];
151
152 const k = key + "Rollup";
153
154 const t = {
155 [k]: () => gulp.src(src)
156 .pipe(rollupPipe(...(options || getDefaultRollupOptions())))
157 .pipe(gulp.dest(dest)),
158 [k + "Watch"]: () => gulp.watch(src, t[key + "Rollup"])
159 }
160
161 tasks[k] = t[k];
162 rollupTasks.push(t[k]);
163 watchTasks.push(t[k + "Watch"]);
164 }
165
166 rollupTask = gulp.parallel(...rollupTasks);
167 }
168
169 }
170
171 if (clean) {
172 const tsClean = () => del(clean);
173 tasks.tsClean = tsClean;
174 cleanTask = tsClean;
175 }
176
177 tsAndRollup = [ts];
178 if (rollupTask || declarationsTask) { // rollup and decl copy can be parallel
179 const t = [];
180 if (rollupTask) t.push(rollupTask);
181 if (declarationsTask) t.push(declarationsTask);
182
183 tsAndRollup.push(t.length > 1 ? gulp.parallel(...t) : t[0]);
184 }
185 if (cleanTask) tsAndRollup.push(cleanTask);
186
187 tasks.ts = ts;
188 parallelBuildTasks.push(tsAndRollup.length > 1 ? gulp.series(...tsAndRollup) : ts); // TODO: Include Rollup and delete temp directory
189 watchTasks.push(tsWatch);
190 }
191
192
193 /**
194 * Setup deploy tasks (or deploy and repload if also using serve with browserSync)
195 */
196 if (include.deploy) {
197 const cache = require("gulp-cached");
198
199 const {src, dest} = include.deploy;
200
201 const deploy = () => gulp.src(src)
202 .pipe(gulp.dest(dest));
203
204
205 if (include.serve) {
206 const deployAndReload = () => gulp.src(src)
207 .pipe(cache('deploy'))
208 .pipe(gulp.dest(dest))
209 .pipe(browserSync.stream())
210
211 const deployWatch = () => gulp.watch(src, deployAndReload);
212
213 watchTasks.push(deployWatch);
214 } else {
215 const deployWatch = () => gulp.watch(src, deploy);
216
217 watchTasks.push(deployWatch);
218 }
219
220 tasks.deploy = deploy;
221 deployTask = deploy;
222 }
223
224
225 if (include.serve) {
226 const browserSync = require("browser-sync");
227
228 const {proxy, sslKey, sslCert} = include.serve;
229
230 let https = sslKey || sslCert ?
231 {
232 key: sslKey,
233 cert: sslCert
234 } : undefined;
235
236 /**
237 * Serve with BrowserSync
238 */
239 serveTask = done => {
240 browserSync.init({
241 proxy,
242 https
243 })
244 done();
245 }
246 }
247
248
249
250 /**
251 * Setup main build and watch tasks
252 */
253 const buildTasks = [];
254 if (cleanTask) buildTasks.push(cleanTask);
255 if (parallelBuildTasks.length > 0) buildTasks.push(gulp.parallel(...parallelBuildTasks));
256
257 const watch = watchTasks.length > 0 ? gulp.parallel(...watchTasks) : done => done(); // TODO: Don't even add watch if no watch tasks defined
258 const build = gulp.series(...buildTasks);
259
260
261 const buildAndWatchTasks = [build];
262 if (deployTask) buildAndWatchTasks.push(deployTask);
263 if (serveTask) buildAndWatchTasks.push(serveTask);
264 buildAndWatchTasks.push(watch);
265
266 const buildAndWatch = gulp.series(...buildAndWatchTasks);//build, /* deploy, serve, */ watch); // Not finished
267
268 return {
269 ...tasks,
270 watch,
271 build,
272 buildAndWatch,
273 default: buildAndWatch
274 }
275}
276
277/**
278 * Create many copy tasks named after given keys with src and dest arrays
279 * @param {*} copyDefs
280 */
281const createCopyAll = (copyDefs) => {
282 let tasks = {};
283 const parallelBuildTasks = [];
284 const watchTasks = [];
285
286 for (const key of Object.keys(copyDefs)) {
287 const [src, dest] = copyDefs[key];
288 const result = createCopy(key, src, dest)
289
290 tasks = {...tasks, ...result};
291 parallelBuildTasks.push(result[key]);
292 watchTasks.push(result[key + "Watch"]);
293 }
294
295 return {
296 tasks,
297 parallelBuildTasks,
298 watchTasks
299 }
300}
301
302/**
303 * Generate a copy function for Gulp
304 * @param {*} src
305 * @param {*} dest
306 */
307const createCopy = (name, src, dest) => {
308 const result = {
309 [name]: () => gulp.src(src).pipe(gulp.dest(dest)),
310 [name + "Watch"]: () => gulp.watch(src, result[name])
311 }
312 return result;
313 const copy = () => gulp.src(src).pipe(gulp.dest(dest));
314 const copyWatch = () => gulp.watch(src, copy);
315
316 return {copy, copyWatch};
317}
318
319/**
320 * Creates a sass pipe for Gulp
321 * @param {*} src
322 * @param {*} dest
323 */
324const createSass = (src, dest, watchSrc) => {
325 const scss = () => gulp.src(src)
326 .pipe(sass()) // TODO: allow options like csso, minification, sourcemaps, and logging
327 .pipe(gulp.dest(dest))
328
329 const scssWatch = () => gulp.watch(watchSrc || src, scss);
330
331 return {scss, scssWatch}
332}
333
334/**
335 * Create a typescript pipe for Gulp
336 * @param {*} src
337 * @param {*} dest
338 * @param {*} config
339 */
340const createTypeScript = (src, dest, config = "tsconfig.json") => {
341 const ts = () => gulp.src(src)
342 .pipe(typescript.createProject("tsconfig.json")())
343 .pipe(gulp.dest(dest));
344
345 const tsWatch = () => gulp.watch(src, ts);
346
347 return {ts, tsWatch};
348}
349
350
351
352module.exports = {
353 createGulpfile
354}
\No newline at end of file