-
Notifications
You must be signed in to change notification settings - Fork 0
/
gulpfile.js
193 lines (167 loc) · 6.76 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
// -----------------------------------------------------------------------------
// Imports
// -----------------------------------------------------------------------------
const advpng = require('imagemin-advpng');
const chalk = require('chalk');
const childProcess = require('child_process');
const fs = require('fs');
const gulp = require('gulp');
const log = require('fancy-log');
const rollup = require('rollup');
const rollupJson = require('@rollup/plugin-json');
const AsepriteCli = require('./tools/aseprite-cli');
const ImageDataParser = require('./tools/image-data-parser');
// -----------------------------------------------------------------------------
// Gulp Plugins
// -----------------------------------------------------------------------------
const concat = require('gulp-concat');
const cleancss = require('gulp-clean-css');
const htmlmin = require('gulp-htmlmin');
const imagemin = require('gulp-imagemin');
const rename = require('gulp-rename');
const size = require('gulp-size');
const sourcemaps = require('gulp-sourcemaps');
const template = require('gulp-template');
const terser = require('gulp-terser');
// -----------------------------------------------------------------------------
// Flags
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// JS Build
// -----------------------------------------------------------------------------
async function generateGameVersion() {
let file = 'src/js/GameVersion-gen.json';
let data = {
GameVersion: require('./package.json').version
};
fs.writeFileSync(file, JSON.stringify(data, undefined, 4), 'utf8');
}
async function compileBuild() {
try {
const bundle = await rollup.rollup({
input: 'src/js/index.js',
plugins: rollupJson(),
onwarn: (warning, rollupWarn) => {
// Suppress circular dependency warnings
// (I use circular dependencies with wild abandon)
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
rollupWarn(warning);
}
}
});
await bundle.write({
file: 'temp/app.js',
format: 'iife',
name: 'app',
sourcemap: 'inline'
});
} catch (error) {
// Use rollup's error output
// This hack is for development - I'm using rollup's API here, but I want
// the output format of the CLI if I have a compile/syntax error. The line
// below invokes the CLI's error handling so I can see the detailed context.
require('rollup/dist/shared/loadConfigFile').handleError(error, true);
throw error;
}
}
function minifyBuild() {
return gulp.src('temp/app.js')
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(terser({
// I'm using terser to shrink the JS source size down, every little bit helps
// for loading speed in the browser -- but we don't need it to be mangled
// or intentionally obfuscated.
mangle: false
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist'));
}
const buildJs = gulp.series(generateGameVersion, compileBuild, minifyBuild);
// -----------------------------------------------------------------------------
// CSS Build
// -----------------------------------------------------------------------------
function buildCss() {
return gulp.src('src/app.css')
.pipe(cleancss())
.pipe(gulp.dest('dist'));
}
// -----------------------------------------------------------------------------
// Assets Build
// -----------------------------------------------------------------------------
async function exportSpriteSheet() {
// Exporting the sprite sheet is the first step - using Aseprite, we take as input
// all of our source aseprite files, and spit out a single spritesheet PNG and a JSON
// file containing the x/y/w/h coordinates of the sprites in the spritesheet.
let src = 'src/assets/*.aseprite';
let png = 'src/assets/spritesheet-gen.png';
let data = 'src/assets/spritesheet-gen.json';
try {
let r = await AsepriteCli.exec(`--batch ${src} --sheet-type packed --sheet ${png} --data ${data} --format json-array`);
log.info(r);
} catch (e) {
log.error(e);
log.warn(chalk.red('Failed to update sprite sheet, but building anyway...'));
}
}
async function generateSpriteSheetData() {
// After exporting the sprite sheet, we use the JSON data to update a source file used by
// our asset loader in the game. This way we can freely update images without ever
// hand-edting any coordinate data or worrying about the composition of the spritesheet.
let data = 'src/assets/spritesheet-gen.json';
let image = 'sprites.png';
let output = 'src/js/SpriteSheet-gen.js';
await ImageDataParser.parse(data, image, false, output);
}
function copyAssets() {
return gulp.src('src/assets/spritesheet-gen.png')
.pipe(rename('sprites.png'))
.pipe(gulp.dest('dist'));
}
const buildAssets = gulp.series(
exportSpriteSheet,
copyAssets,
generateSpriteSheetData,
);
// -----------------------------------------------------------------------------
// HTML Build
// -----------------------------------------------------------------------------
function buildHtml() {
return gulp.src('src/index.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('dist'));
}
// -----------------------------------------------------------------------------
// Build
// -----------------------------------------------------------------------------
const build = gulp.series(
buildAssets,
buildJs,
buildCss,
buildHtml
);
// -----------------------------------------------------------------------------
// Watch
// -----------------------------------------------------------------------------
function watch() {
watching = true;
// The watch task watches for any file changes in the src/ folder, _except_ for
// edits to generated files (called blah-gen by convention).
gulp.watch(['src/**', '!src/**/*-gen*'], build);
}
// -----------------------------------------------------------------------------
// Task List
// -----------------------------------------------------------------------------
module.exports = {
// Potentially useful subtasks
compileBuild,
minifyBuild,
// Core build steps
buildJs,
buildCss,
buildAssets,
buildHtml,
// Primary entry points
build,
watch,
default: gulp.series(build, watch)
};