UNPKG

9.88 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 {src, dest, tsconfig, clean} = include.ts;
104 const {ts, tsWatch} = createTypeScript(src, dest, tsconfig);
105
106 let rollupTask;
107 let declarationsTask;
108 let cleanTask;
109
110 const declarationOptions = include.ts.declarations;
111
112 if (declarationOptions) {
113 const {src, dest} = declarationOptions;
114
115 const declarations = () => gulp.src(src)
116 .pipe(gulp.dest(dest));
117
118 const declarationsWatch = () => gulp.watch(src, declarations);
119
120 tasks.declarations = declarations;
121 declarationsTask = declarations;
122 watchTasks.push(declarationsWatch);
123 }
124
125 let rollupOptions = include.ts.rollup; // To deal with variable/constant scope and same-named variables
126
127 if (rollupOptions) {
128 const rollupPipe = require("gulp-better-rollup");
129 const uglify = require("gulp-uglify");
130
131 let single = rollupOptions.src && rollupOptions.dest;
132
133 if (single) {
134 const {src, dest, options} = rollupOptions;
135
136 const rollup = () => gulp.src(src)
137 .pipe(rollupPipe(...(options || getDefaultRollupOptions())))
138 .pipe(uglify())
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(uglify())
158 .pipe(gulp.dest(dest)),
159 [k + "Watch"]: () => gulp.watch(src, t[key + "Rollup"])
160 }
161
162 tasks[k] = t[k];
163 rollupTasks.push(t[k]);
164 watchTasks.push(t[k + "Watch"]);
165 }
166
167 rollupTask = gulp.parallel(...rollupTasks);
168 }
169
170 }
171
172 if (clean) {
173 const tsClean = () => del(clean);
174 tasks.tsClean = tsClean;
175 cleanTask = tsClean;
176 }
177
178 tsAndRollup = [ts];
179 if (rollupTask || declarationsTask) { // rollup and decl copy can be parallel
180 const t = [];
181 if (rollupTask) t.push(rollupTask);
182 if (declarationsTask) t.push(declarationsTask);
183
184 tsAndRollup.push(t.length > 1 ? gulp.parallel(...t) : t[0]);
185 }
186 if (cleanTask) tsAndRollup.push(cleanTask);
187
188 tasks.ts = ts;
189 parallelBuildTasks.push(tsAndRollup.length > 1 ? gulp.series(...tsAndRollup) : ts); // TODO: Include Rollup and delete temp directory
190 watchTasks.push(tsWatch);
191 }
192
193
194
195 let browserSync = null;
196 if (include.deploy || include.serve) {
197 browserSync = require("browser-sync");
198 }
199
200
201 /**
202 * Setup deploy tasks (or deploy and repload if also using serve with browserSync)
203 */
204 if (include.deploy) {
205 const cache = require("gulp-cached");
206
207 const {src, dest} = include.deploy;
208
209 const deploy = () => gulp.src(src)
210 .pipe(gulp.dest(dest));
211
212
213 if (include.serve) {
214 const deployAndReload = () => gulp.src(src)
215 .pipe(cache('deploy'))
216 .pipe(gulp.dest(dest))
217 .pipe(browserSync.stream())
218
219 const deployWatch = () => gulp.watch(src, deployAndReload);
220
221 watchTasks.push(deployWatch);
222 } else {
223 const deployWatch = () => gulp.watch(src, deploy);
224
225 watchTasks.push(deployWatch);
226 }
227
228 tasks.deploy = deploy;
229 deployTask = deploy;
230 }
231
232
233 if (include.serve) {
234 const {proxy, sslKey, sslCert} = include.serve;
235
236 let https = sslKey || sslCert ?
237 {
238 key: sslKey,
239 cert: sslCert
240 } : undefined;
241
242 /**
243 * Serve with BrowserSync
244 */
245 serveTask = done => {
246 browserSync.init({
247 proxy,
248 https
249 })
250 done();
251 }
252 }
253
254
255
256 /**
257 * Setup main build and watch tasks
258 */
259 const buildTasks = [];
260 if (cleanTask) buildTasks.push(cleanTask);
261 if (parallelBuildTasks.length > 0) buildTasks.push(gulp.parallel(...parallelBuildTasks));
262
263 const watch = watchTasks.length > 0 ? gulp.parallel(...watchTasks) : done => done(); // TODO: Don't even add watch if no watch tasks defined
264 const build = gulp.series(...buildTasks);
265
266
267 const buildAndWatchTasks = [build];
268 if (deployTask) buildAndWatchTasks.push(deployTask);
269 if (serveTask) buildAndWatchTasks.push(serveTask);
270 buildAndWatchTasks.push(watch);
271
272 const buildAndWatch = gulp.series(...buildAndWatchTasks);//build, /* deploy, serve, */ watch); // Not finished
273
274 return {
275 ...tasks,
276 watch,
277 build,
278 buildAndWatch,
279 default: buildAndWatch
280 }
281}
282
283/**
284 * Create many copy tasks named after given keys with src and dest arrays
285 * @param {*} copyDefs
286 */
287const createCopyAll = (copyDefs) => {
288 let tasks = {};
289 const parallelBuildTasks = [];
290 const watchTasks = [];
291
292 for (const key of Object.keys(copyDefs)) {
293 const [src, dest] = copyDefs[key];
294 const result = createCopy(key, src, dest)
295
296 tasks = {...tasks, ...result};
297 parallelBuildTasks.push(result[key]);
298 watchTasks.push(result[key + "Watch"]);
299 }
300
301 return {
302 tasks,
303 parallelBuildTasks,
304 watchTasks
305 }
306}
307
308/**
309 * Generate a copy function for Gulp
310 * @param {*} src
311 * @param {*} dest
312 */
313const createCopy = (name, src, dest) => {
314 const result = {
315 [name]: () => gulp.src(src).pipe(gulp.dest(dest)),
316 [name + "Watch"]: () => gulp.watch(src, result[name])
317 }
318 return result;
319 const copy = () => gulp.src(src).pipe(gulp.dest(dest));
320 const copyWatch = () => gulp.watch(src, copy);
321
322 return {copy, copyWatch};
323}
324
325/**
326 * Creates a sass pipe for Gulp
327 * @param {*} src
328 * @param {*} dest
329 */
330const createSass = (src, dest, watchSrc) => {
331 const scss = () => gulp.src(src)
332 .pipe(sass()) // TODO: allow options like csso, minification, sourcemaps, and logging
333 .pipe(gulp.dest(dest))
334
335 const scssWatch = () => gulp.watch(watchSrc || src, scss);
336
337 return {scss, scssWatch}
338}
339
340/**
341 * Create a typescript pipe for Gulp
342 * @param {*} src
343 * @param {*} dest
344 * @param {*} config
345 */
346const createTypeScript = (src, dest, config = "tsconfig.json") => {
347 const typescript = require("gulp-typescript");
348
349 const ts = () => gulp.src(src)
350 .pipe(typescript.createProject("tsconfig.json")())
351 .pipe(gulp.dest(dest));
352
353 const tsWatch = () => gulp.watch(src, ts);
354
355 return {ts, tsWatch};
356}
357
358
359
360module.exports = {
361 createGulpfile
362}
\No newline at end of file