-
Notifications
You must be signed in to change notification settings - Fork 12
/
gulpfile.mjs
138 lines (116 loc) · 5.39 KB
/
gulpfile.mjs
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
// FIRST LOAD EVERYTHING NEEDED
import { deleteAsync } from "del";
import gulp from "gulp";
import sass from "gulp-dart-sass";
import sourcemaps from "gulp-sourcemaps";
import postcss from "gulp-postcss";
import autoprefixer from "autoprefixer";
import uncss from "postcss-uncss";
import csso from "gulp-csso";
import browserSync from "browser-sync";
import { spawn } from "node:child_process";
const { series, parallel, src, dest, watch } = gulp;
const browserSyncInstance = browserSync.create();
// DEFINE FUNCTIONS
// 1) functions to delete parts of generated files in generated folder
// delete all files
const cleanupAll = () =>
deleteAsync([
"static/generated/**/*", // delete all files from /dist/
"!static/generated/**/.gitkeep", // except HTML, CSS and CSS map files
]);
// delete all CSS files and their sourcemaps
const cleanupCss = () => deleteAsync("static/generated/**/*.{css,css.map}");
const copyStatic = () =>
src([
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js", // get JS bundle from currently used Bootstrap
// Sourcemap is also required, because it is referenced from comment in bootstrap.bundle.min.js:
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js.map",
// "node_modules/bootstrap/dist/js/bootstrap.min.js",
"node_modules/bootstrap-icons/font/*fonts/**/*",
]).pipe(dest("static/generated"));
// 2) functions that generate files
// create and process CSS
const sassCompile = () =>
src("static_src/scss/index.scss") // this is the source for compilation
.pipe(sourcemaps.init()) // initalizes a sourcemap
.pipe(sass.sync().on("error", sass.logError)) // compile SCSS to CSS and also tell us about a problem if happens
.pipe(
postcss([
autoprefixer, // automatically adds vendor prefixes if needed
// see browserslist in package.json for included browsers
// Official Bootstrap browser support policy:
// https://getbootstrap.com/docs/5.3/getting-started/browsers-devices/#supported-browsers
])
)
.pipe(csso()) // compresses CSS
.pipe(sourcemaps.write("./")) // writes the sourcemap
.pipe(dest("static/generated")) // destination of the resulting CSS
.pipe(browserSyncInstance.stream()); // tell browsersync to inject compiled CSS
// remove unused CSS (classes not used in HTML)
const removeUnusedCss = () =>
src("static/generated/index.css", { allowEmpty: true })
.pipe(
postcss([
uncss({
html: ["templates/**/*.html"],
media: ["print"], // process additional media queries
ignore: [/\.PC-.+/], // provide a list of selectors or regular expressions that should not be removed by UnCSS
stylesheets: ["static/generated/index.css"] // use these stylesheets instead of those extracted from the HTML files
}),
])
)
.pipe(dest("static/generated"));
// 3) functions to watch and serve
// Run Docker (Django server)
const runServer = (cb) => {
const cmd = spawn("make", ["up"], { stdio: "inherit" });
cmd.on("close", function (code) {
console.log("runServer exited with code " + code);
cb(code);
});
};
// development with automatic refreshing after changes to CSS, templates or static files
const startBrowsersync = () =>
browserSyncInstance.init({
// initalize Browsersync
port: 3366, // set different port
open: false, // don’t open browser
ghostMode: false, // clicks, scrolls & form inputs on any device will not be mirrored to all others
reloadOnRestart: true, // reload each browser when Browsersync is restarted
proxy: {
target: "localhost:8000",
cookies: { stripDomain: false },
proxyReq: [
(proxyReq, req) => {
// Assign proxy 'host' header same as current request at Browsersync server
proxyReq.setHeader("Host", req.headers.host);
},
],
},
});
// a function to reload Browsersync
const reloadBrowserSync = async () => {
await new Promise((resolve) => setTimeout(resolve, 300)); // wait 300 ms to execute the reload
browserSyncInstance.reload();
};
// a function to watch for changes
const watchFiles = () => {
// SCSS changed: run task to compile it again
watch("static_src/scss/**/*", processCss);
// templates or data file changed: run task to generate HTML again and reload
watch(["templates/**/*.html"], reloadBrowserSync);
// static files changed (except the generated part): reload
watch(["static/**/*", "!static/generated/**/*"], reloadBrowserSync);
};
// COMPOSE TASKS
const processCss = series(cleanupCss, sassCompile);
// EXPORT PUBLICLY AVAILABLE TASKS
// These tasks can be run with `npx gulp TASKNAME` on command line for example `npx gulp develop`.
// We use them in npm scripts with `gulp TASKNAME` (see package.json).
// development with automatic refreshing (doesn't remove unused CSS)
export const develop = series(cleanupAll, copyStatic, sassCompile, parallel(runServer, startBrowsersync, watchFiles));
// build everything for production
export const build = series(cleanupAll, copyStatic, sassCompile, removeUnusedCss);
// the default task runs when you run just `gulp`
export default build;