parcel 2.0.0-nightly.99 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -1492
- package/lib/cli.js +391 -133
- package/package.json +21 -14
- package/src/.eslintrc.json +1 -1
- package/src/cli.js +326 -146
package/src/cli.js
CHANGED
|
@@ -1,50 +1,70 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {InitialParcelOptions} from '@parcel/types';
|
|
4
4
|
import {BuildError} from '@parcel/core';
|
|
5
|
-
import {NodePackageManager} from '@parcel/package-manager';
|
|
6
5
|
import {NodeFS} from '@parcel/fs';
|
|
7
6
|
import ThrowableDiagnostic from '@parcel/diagnostic';
|
|
8
|
-
import {prettyDiagnostic} from '@parcel/utils';
|
|
7
|
+
import {prettyDiagnostic, openInBrowser} from '@parcel/utils';
|
|
8
|
+
import {Disposable} from '@parcel/events';
|
|
9
|
+
import {INTERNAL_ORIGINAL_CONSOLE} from '@parcel/logger';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import commander from 'commander';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import getPort from 'get-port';
|
|
14
|
+
import {version} from '../package.json';
|
|
9
15
|
|
|
10
16
|
require('v8-compile-cache');
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
const program = new commander.Command();
|
|
19
|
+
|
|
20
|
+
// Exit codes in response to signals are traditionally
|
|
21
|
+
// 128 + signal value
|
|
22
|
+
// https://tldp.org/LDP/abs/html/exitcodes.html
|
|
23
|
+
const SIGINT_EXIT_CODE = 130;
|
|
24
|
+
|
|
25
|
+
async function logUncaughtError(e: mixed) {
|
|
13
26
|
if (e instanceof ThrowableDiagnostic) {
|
|
14
27
|
for (let diagnostic of e.diagnostics) {
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
let {message, codeframe, stack, hints, documentation} =
|
|
29
|
+
await prettyDiagnostic(diagnostic);
|
|
30
|
+
INTERNAL_ORIGINAL_CONSOLE.error(chalk.red(message));
|
|
31
|
+
if (codeframe || stack) {
|
|
32
|
+
INTERNAL_ORIGINAL_CONSOLE.error('');
|
|
33
|
+
}
|
|
34
|
+
INTERNAL_ORIGINAL_CONSOLE.error(codeframe);
|
|
35
|
+
INTERNAL_ORIGINAL_CONSOLE.error(stack);
|
|
36
|
+
if ((stack || codeframe) && hints.length > 0) {
|
|
37
|
+
INTERNAL_ORIGINAL_CONSOLE.error('');
|
|
38
|
+
}
|
|
39
|
+
for (let h of hints) {
|
|
40
|
+
INTERNAL_ORIGINAL_CONSOLE.error(chalk.blue(h));
|
|
41
|
+
}
|
|
42
|
+
if (documentation) {
|
|
43
|
+
INTERNAL_ORIGINAL_CONSOLE.error(chalk.magenta.bold(documentation));
|
|
20
44
|
}
|
|
21
45
|
}
|
|
22
46
|
} else {
|
|
23
|
-
|
|
47
|
+
INTERNAL_ORIGINAL_CONSOLE.error(e);
|
|
24
48
|
}
|
|
49
|
+
|
|
50
|
+
// A hack to definitely ensure we logged the uncaught exception
|
|
51
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
25
52
|
}
|
|
26
53
|
|
|
27
|
-
|
|
28
|
-
|
|
54
|
+
const handleUncaughtException = async exception => {
|
|
55
|
+
try {
|
|
56
|
+
await logUncaughtError(exception);
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error(exception);
|
|
59
|
+
console.error(err);
|
|
60
|
+
}
|
|
61
|
+
|
|
29
62
|
process.exit(1);
|
|
30
|
-
}
|
|
63
|
+
};
|
|
31
64
|
|
|
32
|
-
|
|
33
|
-
const program = require('commander');
|
|
34
|
-
const path = require('path');
|
|
35
|
-
const getPort = require('get-port');
|
|
36
|
-
const version = require('../package.json').version;
|
|
37
|
-
|
|
38
|
-
// Capture the NODE_ENV this process was launched with, so that it can be
|
|
39
|
-
// used in Parcel (such as in process.env inlining).
|
|
40
|
-
const initialNodeEnv = process.env.NODE_ENV;
|
|
41
|
-
// Then, override NODE_ENV to be PARCEL_BUILD_ENV (replaced with `production` in builds)
|
|
42
|
-
// so that dependencies of Parcel like React (which renders the cli through `ink`)
|
|
43
|
-
// run in the appropriate mode.
|
|
44
|
-
if (typeof process.env.PARCEL_BUILD_ENV === 'string') {
|
|
45
|
-
process.env.NODE_ENV = process.env.PARCEL_BUILD_ENV;
|
|
46
|
-
}
|
|
65
|
+
process.on('unhandledRejection', handleUncaughtException);
|
|
47
66
|
|
|
67
|
+
program.storeOptionsAsProperties();
|
|
48
68
|
program.version(version);
|
|
49
69
|
|
|
50
70
|
// --no-cache, --cache-dir, --no-source-maps, --no-autoinstall, --global?, --public-url, --log-level
|
|
@@ -52,57 +72,77 @@ program.version(version);
|
|
|
52
72
|
|
|
53
73
|
const commonOptions = {
|
|
54
74
|
'--no-cache': 'disable the filesystem cache',
|
|
75
|
+
'--config <path>':
|
|
76
|
+
'specify which config to use. can be a path or a package name',
|
|
55
77
|
'--cache-dir <path>': 'set the cache directory. defaults to ".parcel-cache"',
|
|
56
78
|
'--no-source-maps': 'disable sourcemaps',
|
|
57
|
-
'--no-autoinstall': 'disable autoinstall',
|
|
58
79
|
'--target [name]': [
|
|
59
80
|
'only build given target(s)',
|
|
60
81
|
(val, list) => list.concat([val]),
|
|
61
82
|
[],
|
|
62
83
|
],
|
|
63
|
-
'--log-level <level>':
|
|
64
|
-
'
|
|
65
|
-
|
|
66
|
-
],
|
|
84
|
+
'--log-level <level>': new commander.Option(
|
|
85
|
+
'--log-level <level>',
|
|
86
|
+
'set the log level',
|
|
87
|
+
).choices(['none', 'error', 'warn', 'info', 'verbose']),
|
|
88
|
+
'--dist-dir <dir>':
|
|
89
|
+
'output directory to write to when unspecified by targets',
|
|
90
|
+
'--no-autoinstall': 'disable autoinstall',
|
|
67
91
|
'--profile': 'enable build profiling',
|
|
68
92
|
'-V, --version': 'output the version number',
|
|
93
|
+
'--detailed-report [count]': [
|
|
94
|
+
'print the asset timings and sizes in the build report',
|
|
95
|
+
parseOptionInt,
|
|
96
|
+
],
|
|
97
|
+
'--reporter <name>': [
|
|
98
|
+
'additional reporters to run',
|
|
99
|
+
(val, acc) => {
|
|
100
|
+
acc.push(val);
|
|
101
|
+
return acc;
|
|
102
|
+
},
|
|
103
|
+
[],
|
|
104
|
+
],
|
|
69
105
|
};
|
|
70
106
|
|
|
71
107
|
var hmrOptions = {
|
|
72
108
|
'--no-hmr': 'disable hot module replacement',
|
|
109
|
+
'-p, --port <port>': [
|
|
110
|
+
'set the port to serve on. defaults to $PORT or 1234',
|
|
111
|
+
process.env.PORT,
|
|
112
|
+
],
|
|
113
|
+
'--host <host>':
|
|
114
|
+
'set the host to listen on, defaults to listening on all interfaces',
|
|
73
115
|
'--https': 'serves files over HTTPS',
|
|
74
116
|
'--cert <path>': 'path to certificate to use with HTTPS',
|
|
75
117
|
'--key <path>': 'path to private key to use with HTTPS',
|
|
118
|
+
'--hmr-port <port>': ['hot module replacement port', process.env.HMR_PORT],
|
|
76
119
|
};
|
|
77
120
|
|
|
78
121
|
function applyOptions(cmd, options) {
|
|
79
122
|
for (let opt in options) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
123
|
+
const option = options[opt];
|
|
124
|
+
if (option instanceof commander.Option) {
|
|
125
|
+
cmd.addOption(option);
|
|
126
|
+
} else {
|
|
127
|
+
cmd.option(opt, ...(Array.isArray(option) ? option : [option]));
|
|
128
|
+
}
|
|
84
129
|
}
|
|
85
130
|
}
|
|
86
131
|
|
|
87
132
|
let serve = program
|
|
88
133
|
.command('serve [input...]')
|
|
89
134
|
.description('starts a development server')
|
|
90
|
-
.option(
|
|
91
|
-
'-p, --port <port>',
|
|
92
|
-
'set the port to serve on. defaults to 1234',
|
|
93
|
-
parseInt,
|
|
94
|
-
)
|
|
95
135
|
.option('--public-url <url>', 'the path prefix for absolute urls')
|
|
96
|
-
.option(
|
|
97
|
-
'--host <host>',
|
|
98
|
-
'set the host to listen on, defaults to listening on all interfaces',
|
|
99
|
-
)
|
|
100
136
|
.option(
|
|
101
137
|
'--open [browser]',
|
|
102
138
|
'automatically open in specified browser, defaults to default browser',
|
|
103
139
|
)
|
|
104
140
|
.option('--watch-for-stdin', 'exit when stdin closes')
|
|
105
|
-
.
|
|
141
|
+
.option(
|
|
142
|
+
'--lazy',
|
|
143
|
+
'Build async bundles on demand, when requested in the browser',
|
|
144
|
+
)
|
|
145
|
+
.action(runCommand);
|
|
106
146
|
|
|
107
147
|
applyOptions(serve, hmrOptions);
|
|
108
148
|
applyOptions(serve, commonOptions);
|
|
@@ -110,13 +150,10 @@ applyOptions(serve, commonOptions);
|
|
|
110
150
|
let watch = program
|
|
111
151
|
.command('watch [input...]')
|
|
112
152
|
.description('starts the bundler in watch mode')
|
|
113
|
-
.option(
|
|
114
|
-
'--dist-dir <dir>',
|
|
115
|
-
'output directory to write to when unspecified by targets',
|
|
116
|
-
)
|
|
117
153
|
.option('--public-url <url>', 'the path prefix for absolute urls')
|
|
154
|
+
.option('--no-content-hash', 'disable content hashing')
|
|
118
155
|
.option('--watch-for-stdin', 'exit when stdin closes')
|
|
119
|
-
.action(
|
|
156
|
+
.action(runCommand);
|
|
120
157
|
|
|
121
158
|
applyOptions(watch, hmrOptions);
|
|
122
159
|
applyOptions(watch, commonOptions);
|
|
@@ -124,143 +161,237 @@ applyOptions(watch, commonOptions);
|
|
|
124
161
|
let build = program
|
|
125
162
|
.command('build [input...]')
|
|
126
163
|
.description('bundles for production')
|
|
127
|
-
.option('--no-
|
|
164
|
+
.option('--no-optimize', 'disable minification')
|
|
128
165
|
.option('--no-scope-hoist', 'disable scope-hoisting')
|
|
129
166
|
.option('--public-url <url>', 'the path prefix for absolute urls')
|
|
130
|
-
.option(
|
|
131
|
-
|
|
132
|
-
'Output directory to write to when unspecified by targets',
|
|
133
|
-
)
|
|
134
|
-
.action(run);
|
|
167
|
+
.option('--no-content-hash', 'disable content hashing')
|
|
168
|
+
.action(runCommand);
|
|
135
169
|
|
|
136
170
|
applyOptions(build, commonOptions);
|
|
137
171
|
|
|
138
172
|
program
|
|
139
173
|
.command('help [command]')
|
|
140
174
|
.description('display help information for a command')
|
|
141
|
-
.action(function(command) {
|
|
175
|
+
.action(function (command) {
|
|
142
176
|
let cmd = program.commands.find(c => c.name() === command) || program;
|
|
143
177
|
cmd.help();
|
|
144
178
|
});
|
|
145
179
|
|
|
146
|
-
program.on('--help', function() {
|
|
147
|
-
|
|
148
|
-
|
|
180
|
+
program.on('--help', function () {
|
|
181
|
+
INTERNAL_ORIGINAL_CONSOLE.log('');
|
|
182
|
+
INTERNAL_ORIGINAL_CONSOLE.log(
|
|
149
183
|
' Run `' +
|
|
150
184
|
chalk.bold('parcel help <command>') +
|
|
151
185
|
'` for more information on specific commands',
|
|
152
186
|
);
|
|
153
|
-
|
|
187
|
+
INTERNAL_ORIGINAL_CONSOLE.log('');
|
|
154
188
|
});
|
|
155
189
|
|
|
190
|
+
// Override to output option description if argument was missing
|
|
191
|
+
commander.Command.prototype.optionMissingArgument = function (option) {
|
|
192
|
+
INTERNAL_ORIGINAL_CONSOLE.error(
|
|
193
|
+
"error: option `%s' argument missing",
|
|
194
|
+
option.flags,
|
|
195
|
+
);
|
|
196
|
+
INTERNAL_ORIGINAL_CONSOLE.log(program.createHelp().optionDescription(option));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
};
|
|
199
|
+
|
|
156
200
|
// Make serve the default command except for --help
|
|
157
201
|
var args = process.argv;
|
|
158
202
|
if (args[2] === '--help' || args[2] === '-h') args[2] = 'help';
|
|
203
|
+
|
|
159
204
|
if (!args[2] || !program.commands.some(c => c.name() === args[2])) {
|
|
160
205
|
args.splice(2, 0, 'serve');
|
|
161
206
|
}
|
|
162
207
|
|
|
163
208
|
program.parse(args);
|
|
164
209
|
|
|
165
|
-
|
|
166
|
-
|
|
210
|
+
function runCommand(...args) {
|
|
211
|
+
run(...args).catch(handleUncaughtException);
|
|
212
|
+
}
|
|
167
213
|
|
|
214
|
+
async function run(
|
|
215
|
+
entries: Array<string>,
|
|
216
|
+
_opts: any, // using pre v7 Commander options as properties
|
|
217
|
+
command: any,
|
|
218
|
+
) {
|
|
168
219
|
if (entries.length === 0) {
|
|
169
|
-
|
|
170
|
-
return;
|
|
220
|
+
entries = ['.'];
|
|
171
221
|
}
|
|
222
|
+
|
|
223
|
+
entries = entries.map(entry => path.resolve(entry));
|
|
224
|
+
|
|
172
225
|
let Parcel = require('@parcel/core').default;
|
|
173
|
-
let
|
|
174
|
-
let
|
|
175
|
-
'@parcel/config-default',
|
|
176
|
-
__filename,
|
|
177
|
-
);
|
|
226
|
+
let fs = new NodeFS();
|
|
227
|
+
let options = await normalizeOptions(command, fs);
|
|
178
228
|
let parcel = new Parcel({
|
|
179
229
|
entries,
|
|
180
|
-
|
|
181
|
-
defaultConfig: {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
},
|
|
187
|
-
patchConsole: true,
|
|
188
|
-
...(await normalizeOptions(command)),
|
|
230
|
+
// $FlowFixMe[extra-arg] - flow doesn't know about the `paths` option (added in Node v8.9.0)
|
|
231
|
+
defaultConfig: require.resolve('@parcel/config-default', {
|
|
232
|
+
paths: [fs.cwd(), __dirname],
|
|
233
|
+
}),
|
|
234
|
+
shouldPatchConsole: true,
|
|
235
|
+
...options,
|
|
189
236
|
});
|
|
190
237
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
238
|
+
let disposable = new Disposable();
|
|
239
|
+
let unsubscribe: () => Promise<mixed>;
|
|
240
|
+
let isExiting;
|
|
241
|
+
async function exit(exitCode: number = 0) {
|
|
242
|
+
if (isExiting) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
197
245
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
246
|
+
isExiting = true;
|
|
247
|
+
if (unsubscribe != null) {
|
|
248
|
+
await unsubscribe();
|
|
249
|
+
} else if (parcel.isProfiling) {
|
|
250
|
+
await parcel.stopProfiling();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (process.stdin.isTTY && process.stdin.isRaw) {
|
|
254
|
+
// $FlowFixMe
|
|
255
|
+
process.stdin.setRawMode(false);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
disposable.dispose();
|
|
259
|
+
process.exit(exitCode);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const isWatching = command.name() === 'watch' || command.name() === 'serve';
|
|
263
|
+
if (process.stdin.isTTY) {
|
|
264
|
+
// $FlowFixMe
|
|
265
|
+
process.stdin.setRawMode(true);
|
|
266
|
+
require('readline').emitKeypressEvents(process.stdin);
|
|
267
|
+
|
|
268
|
+
let stream = process.stdin.on('keypress', async (char, key) => {
|
|
269
|
+
if (!key.ctrl) {
|
|
201
270
|
return;
|
|
202
271
|
}
|
|
203
272
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
273
|
+
switch (key.name) {
|
|
274
|
+
case 'c':
|
|
275
|
+
// Detect the ctrl+c key, and gracefully exit after writing the asset graph to the cache.
|
|
276
|
+
// This is mostly for tools that wrap Parcel as a child process like yarn and npm.
|
|
277
|
+
//
|
|
278
|
+
// Setting raw mode prevents SIGINT from being sent in response to ctrl-c:
|
|
279
|
+
// https://nodejs.org/api/tty.html#tty_readstream_setrawmode_mode
|
|
280
|
+
//
|
|
281
|
+
// We don't use the SIGINT event for this because when run inside yarn, the parent
|
|
282
|
+
// yarn process ends before Parcel and it appears that Parcel has ended while it may still
|
|
283
|
+
// be cleaning up. Handling events from stdin prevents this impression.
|
|
284
|
+
|
|
285
|
+
// Enqueue a busy message to be shown if Parcel doesn't shut down
|
|
286
|
+
// within the timeout.
|
|
287
|
+
setTimeout(
|
|
288
|
+
() =>
|
|
289
|
+
INTERNAL_ORIGINAL_CONSOLE.log(
|
|
290
|
+
chalk.bold.yellowBright('Parcel is shutting down...'),
|
|
291
|
+
),
|
|
292
|
+
500,
|
|
293
|
+
);
|
|
294
|
+
// When watching, a 0 success code is acceptable when Parcel is interrupted with ctrl-c.
|
|
295
|
+
// When building, fail with a code as if we received a SIGINT.
|
|
296
|
+
await exit(isWatching ? 0 : SIGINT_EXIT_CODE);
|
|
297
|
+
break;
|
|
298
|
+
case 'e':
|
|
299
|
+
await (parcel.isProfiling
|
|
300
|
+
? parcel.stopProfiling()
|
|
301
|
+
: parcel.startProfiling());
|
|
302
|
+
break;
|
|
303
|
+
case 'y':
|
|
304
|
+
await parcel.takeHeapSnapshot();
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
disposable.add(() => {
|
|
310
|
+
stream.destroy();
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (isWatching) {
|
|
315
|
+
({unsubscribe} = await parcel.watch(err => {
|
|
316
|
+
if (err) {
|
|
317
|
+
throw err;
|
|
318
|
+
}
|
|
319
|
+
}));
|
|
320
|
+
|
|
321
|
+
if (command.open && options.serveOptions) {
|
|
322
|
+
await openInBrowser(
|
|
323
|
+
`${options.serveOptions.https ? 'https' : 'http'}://${
|
|
324
|
+
options.serveOptions.host || 'localhost'
|
|
325
|
+
}:${options.serveOptions.port}`,
|
|
326
|
+
command.open,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
208
329
|
|
|
209
330
|
if (command.watchForStdin) {
|
|
210
331
|
process.stdin.on('end', async () => {
|
|
211
|
-
|
|
332
|
+
INTERNAL_ORIGINAL_CONSOLE.log('STDIN closed, ending');
|
|
212
333
|
|
|
213
334
|
await exit();
|
|
214
335
|
});
|
|
215
336
|
process.stdin.resume();
|
|
216
337
|
}
|
|
217
338
|
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
// Setting raw mode prevents SIGINT from being sent in response to ctrl-c:
|
|
222
|
-
// https://nodejs.org/api/tty.html#tty_readstream_setrawmode_mode
|
|
223
|
-
//
|
|
224
|
-
// We don't use the SIGINT event for this because when run inside yarn, the parent
|
|
225
|
-
// yarn process ends before Parcel and it appears that Parcel has ended while it may still
|
|
226
|
-
// be cleaning up. Handling events from stdin prevents this impression.
|
|
227
|
-
if (process.stdin.isTTY) {
|
|
228
|
-
// $FlowFixMe
|
|
229
|
-
process.stdin.setRawMode(true);
|
|
230
|
-
require('readline').emitKeypressEvents(process.stdin);
|
|
231
|
-
|
|
232
|
-
process.stdin.on('keypress', async (char, key) => {
|
|
233
|
-
if (key.ctrl && key.name === 'c') {
|
|
234
|
-
await exit();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// In non-tty cases, respond to SIGINT by cleaning up.
|
|
339
|
+
// In non-tty cases, respond to SIGINT by cleaning up. Since we're watching,
|
|
340
|
+
// a 0 success code is acceptable.
|
|
240
341
|
process.on('SIGINT', exit);
|
|
241
342
|
process.on('SIGTERM', exit);
|
|
242
343
|
} else {
|
|
243
344
|
try {
|
|
244
345
|
await parcel.run();
|
|
245
|
-
} catch (
|
|
346
|
+
} catch (err) {
|
|
246
347
|
// If an exception is thrown during Parcel.build, it is given to reporters in a
|
|
247
348
|
// buildFailure event, and has been shown to the user.
|
|
248
|
-
if (!(
|
|
249
|
-
logUncaughtError(
|
|
349
|
+
if (!(err instanceof BuildError)) {
|
|
350
|
+
await logUncaughtError(err);
|
|
250
351
|
}
|
|
251
|
-
|
|
352
|
+
await exit(1);
|
|
252
353
|
}
|
|
354
|
+
|
|
355
|
+
await exit();
|
|
253
356
|
}
|
|
254
357
|
}
|
|
255
358
|
|
|
256
|
-
|
|
359
|
+
function parsePort(portValue: string): number {
|
|
360
|
+
let parsedPort = Number(portValue);
|
|
361
|
+
|
|
362
|
+
// Throw an error if port value is invalid...
|
|
363
|
+
if (!Number.isInteger(parsedPort)) {
|
|
364
|
+
throw new Error(`Port ${portValue} is not a valid integer.`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return parsedPort;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function parseOptionInt(value) {
|
|
371
|
+
const parsedValue = parseInt(value, 10);
|
|
372
|
+
if (isNaN(parsedValue)) {
|
|
373
|
+
throw new commander.InvalidOptionArgumentError('Must be an integer.');
|
|
374
|
+
}
|
|
375
|
+
return parsedValue;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function normalizeOptions(
|
|
379
|
+
command,
|
|
380
|
+
inputFS,
|
|
381
|
+
): Promise<InitialParcelOptions> {
|
|
257
382
|
let nodeEnv;
|
|
258
383
|
if (command.name() === 'build') {
|
|
259
|
-
nodeEnv =
|
|
384
|
+
nodeEnv = process.env.NODE_ENV || 'production';
|
|
385
|
+
// Autoinstall unless explicitly disabled or we detect a CI environment.
|
|
386
|
+
command.autoinstall = !(command.autoinstall === false || process.env.CI);
|
|
260
387
|
} else {
|
|
261
|
-
nodeEnv =
|
|
388
|
+
nodeEnv = process.env.NODE_ENV || 'development';
|
|
262
389
|
}
|
|
263
390
|
|
|
391
|
+
// Set process.env.NODE_ENV to a default if undefined so that it is
|
|
392
|
+
// available in JS configs and plugins.
|
|
393
|
+
process.env.NODE_ENV = nodeEnv;
|
|
394
|
+
|
|
264
395
|
let https = !!command.https;
|
|
265
396
|
if (command.cert && command.key) {
|
|
266
397
|
https = {
|
|
@@ -269,19 +400,41 @@ async function normalizeOptions(command): Promise<InitialParcelOptions> {
|
|
|
269
400
|
};
|
|
270
401
|
}
|
|
271
402
|
|
|
272
|
-
let
|
|
273
|
-
|
|
274
|
-
let {port = 1234, host, publicUrl} = command;
|
|
275
|
-
port = await getPort({port, host});
|
|
403
|
+
let serveOptions = false;
|
|
404
|
+
let {host} = command;
|
|
276
405
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
406
|
+
// Ensure port is valid and available
|
|
407
|
+
let port = parsePort(command.port || '1234');
|
|
408
|
+
let originalPort = port;
|
|
409
|
+
if (command.name() === 'serve' || command.hmr) {
|
|
410
|
+
try {
|
|
411
|
+
port = await getPort({port, host});
|
|
412
|
+
} catch (err) {
|
|
413
|
+
throw new ThrowableDiagnostic({
|
|
414
|
+
diagnostic: {
|
|
415
|
+
message: `Could not get available port: ${err.message}`,
|
|
416
|
+
origin: 'parcel',
|
|
417
|
+
stack: err.stack,
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (port !== originalPort) {
|
|
423
|
+
let errorMessage = `Port "${originalPort}" could not be used`;
|
|
424
|
+
if (command.port != null) {
|
|
425
|
+
// Throw the error if the user defined a custom port
|
|
426
|
+
throw new Error(errorMessage);
|
|
427
|
+
} else {
|
|
428
|
+
// Parcel logger is not set up at this point, so just use native INTERNAL_ORIGINAL_CONSOLE
|
|
429
|
+
INTERNAL_ORIGINAL_CONSOLE.warn(errorMessage);
|
|
430
|
+
}
|
|
282
431
|
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (command.name() === 'serve') {
|
|
435
|
+
let {publicUrl} = command;
|
|
283
436
|
|
|
284
|
-
|
|
437
|
+
serveOptions = {
|
|
285
438
|
https,
|
|
286
439
|
port,
|
|
287
440
|
host,
|
|
@@ -289,29 +442,56 @@ async function normalizeOptions(command): Promise<InitialParcelOptions> {
|
|
|
289
442
|
};
|
|
290
443
|
}
|
|
291
444
|
|
|
292
|
-
let
|
|
445
|
+
let hmrOptions = null;
|
|
293
446
|
if (command.name() !== 'build' && command.hmr !== false) {
|
|
294
|
-
|
|
447
|
+
let hmrport = command.hmrPort ? parsePort(command.hmrPort) : port;
|
|
448
|
+
|
|
449
|
+
hmrOptions = {port: hmrport, host};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (command.detailedReport === true) {
|
|
453
|
+
command.detailedReport = '10';
|
|
295
454
|
}
|
|
296
455
|
|
|
456
|
+
let additionalReporters = [
|
|
457
|
+
{packageName: '@parcel/reporter-cli', resolveFrom: __filename},
|
|
458
|
+
...(command.reporter: Array<string>).map(packageName => ({
|
|
459
|
+
packageName,
|
|
460
|
+
resolveFrom: path.join(inputFS.cwd(), 'index'),
|
|
461
|
+
})),
|
|
462
|
+
];
|
|
463
|
+
|
|
297
464
|
let mode = command.name() === 'build' ? 'production' : 'development';
|
|
298
465
|
return {
|
|
299
|
-
|
|
466
|
+
shouldDisableCache: command.cache === false,
|
|
300
467
|
cacheDir: command.cacheDir,
|
|
468
|
+
config: command.config,
|
|
301
469
|
mode,
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
publicUrl: command.publicUrl,
|
|
306
|
-
distDir: command.distDir,
|
|
307
|
-
hot: hmr,
|
|
308
|
-
serve,
|
|
470
|
+
hmrOptions,
|
|
471
|
+
shouldContentHash: hmrOptions ? false : command.contentHash,
|
|
472
|
+
serveOptions,
|
|
309
473
|
targets: command.target.length > 0 ? command.target : null,
|
|
310
|
-
|
|
474
|
+
shouldAutoInstall: command.autoinstall ?? true,
|
|
311
475
|
logLevel: command.logLevel,
|
|
312
|
-
|
|
476
|
+
shouldProfile: command.profile,
|
|
477
|
+
shouldBuildLazily: command.lazy,
|
|
478
|
+
detailedReport:
|
|
479
|
+
command.detailedReport != null
|
|
480
|
+
? {
|
|
481
|
+
assetsPerBundle: parseInt(command.detailedReport, 10),
|
|
482
|
+
}
|
|
483
|
+
: null,
|
|
313
484
|
env: {
|
|
314
485
|
NODE_ENV: nodeEnv,
|
|
315
486
|
},
|
|
487
|
+
additionalReporters,
|
|
488
|
+
defaultTargetOptions: {
|
|
489
|
+
shouldOptimize:
|
|
490
|
+
command.optimize != null ? command.optimize : mode === 'production',
|
|
491
|
+
sourceMaps: command.sourceMaps ?? true,
|
|
492
|
+
shouldScopeHoist: command.scopeHoist,
|
|
493
|
+
publicUrl: command.publicUrl,
|
|
494
|
+
distDir: command.distDir,
|
|
495
|
+
},
|
|
316
496
|
};
|
|
317
497
|
}
|