-
Notifications
You must be signed in to change notification settings - Fork 798
/
app.ts
155 lines (133 loc) · 4.38 KB
/
app.ts
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
/*
Copyright 2018 Google LLC
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
import {oneLine as ol} from 'common-tags';
import * as workboxBuild from 'workbox-build';
import assert from 'assert';
import {default as chokidar, WatchOptions} from 'chokidar';
import meow from 'meow';
import prettyBytes from 'pretty-bytes';
import upath from 'upath';
import {constants} from './lib/constants.js';
import {errors} from './lib/errors.js';
import {logger} from './lib/logger.js';
import {readConfig} from './lib/read-config.js';
import {runWizard} from './lib/run-wizard.js';
import {SupportedFlags} from './bin.js';
interface BuildCommand {
command: 'generateSW' | 'injectManifest';
config: workboxBuild.GenerateSWOptions | workboxBuild.InjectManifestOptions;
watch: boolean;
}
/**
* Runs the specified build command with the provided configuration.
*
* @param {Object} options
*/
async function runBuildCommand({command, config, watch}: BuildCommand) {
const {count, filePaths, size, warnings} = await workboxBuild[command](
config as any,
);
for (const warning of warnings) {
logger.warn(warning);
}
if (filePaths.length === 1) {
logger.log(`The service worker file was written to ${config.swDest}`);
} else {
const message = filePaths
.sort()
.map((filePath) => ` • ${filePath}`)
.join(`\n`);
logger.log(`The service worker files were written to:\n${message}`);
}
logger.log(
`The service worker will precache ${count} URLs, ` +
`totaling ${prettyBytes(size)}.`,
);
if (watch) {
logger.log(`\nWatching for changes...`);
}
}
export const app = async (
params: meow.Result<SupportedFlags>,
): Promise<void> => {
// This should not be a user-visible error, unless meow() messes something up.
assert(params && Array.isArray(params.input), errors['missing-input']);
// Default to showing the help message if there's no command provided.
const [command = 'help', option] = params.input;
switch (command) {
case 'wizard': {
await runWizard(params.flags);
break;
}
case 'copyLibraries': {
assert(option, errors['missing-dest-dir-param']);
const parentDirectory = upath.resolve(process.cwd(), option);
const dirName = await workboxBuild.copyWorkboxLibraries(parentDirectory);
const fullPath = upath.join(parentDirectory, dirName);
logger.log(`The Workbox libraries were copied to ${fullPath}`);
logger.log(ol`Add a call to workbox.setConfig({modulePathPrefix: '...'})
to your service worker to use these local libraries.`);
logger.log(`See https://goo.gl/Fo9gPX for further documentation.`);
break;
}
case 'generateSW':
case 'injectManifest': {
const configPath = upath.resolve(
process.cwd(),
option || constants.defaultConfigFile,
);
let configFromDisk:
| workboxBuild.GenerateSWOptions
| workboxBuild.InjectManifestOptions;
try {
configFromDisk = readConfig(configPath);
} catch (error) {
if (error instanceof Error) {
logger.error(errors['invalid-common-js-module']);
throw error;
}
}
logger.log(`Using configuration from ${configPath}.`);
const config = configFromDisk!;
// Determine whether we're in --watch mode, or one-off mode.
if (params?.flags?.watch) {
const options: WatchOptions = {
ignoreInitial: true,
};
if (config.globIgnores) {
options.ignored = config.globIgnores;
}
if (config.globDirectory) {
options.cwd = config.globDirectory;
}
if (config.globPatterns) {
chokidar
.watch(config.globPatterns, options)
.on('all', async () => {
await runBuildCommand({command, config, watch: true});
})
.on('ready', async () => {
await runBuildCommand({command, config, watch: true});
})
.on('error', (err) => {
logger.error(err.toString());
});
}
} else {
await runBuildCommand({command, config, watch: false});
}
break;
}
case 'help': {
params.showHelp();
break;
}
default: {
throw new Error(errors['unknown-command'] + ` ` + command);
}
}
};