@atlaspack/cli 2.12.1-dev.3502 → 2.12.1-dev.3520

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/src/cli.js CHANGED
@@ -1,18 +1,22 @@
1
1
  // @flow
2
2
 
3
- import type {InitialAtlaspackOptions} from '@atlaspack/types';
4
3
  import {BuildError} from '@atlaspack/core';
5
4
  import {NodeFS} from '@atlaspack/fs';
6
- import ThrowableDiagnostic from '@atlaspack/diagnostic';
7
- import {prettyDiagnostic, openInBrowser} from '@atlaspack/utils';
5
+ import {openInBrowser} from '@atlaspack/utils';
8
6
  import {Disposable} from '@atlaspack/events';
9
7
  import {INTERNAL_ORIGINAL_CONSOLE} from '@atlaspack/logger';
10
8
  import chalk from 'chalk';
11
9
  import commander from 'commander';
12
10
  import path from 'path';
13
- import getPort from 'get-port';
14
11
  import {version} from '../package.json';
15
- import {DEFAULT_FEATURE_FLAGS} from '@atlaspack/feature-flags';
12
+ import {applyOptions} from './applyOptions';
13
+ import {makeDebugCommand} from './makeDebugCommand';
14
+ import {normalizeOptions} from './normalizeOptions';
15
+ import {
16
+ handleUncaughtException,
17
+ logUncaughtError,
18
+ } from './handleUncaughtException';
19
+ import {commonOptions, hmrOptions} from './options';
16
20
 
17
21
  const program = new commander.Command();
18
22
 
@@ -21,171 +25,11 @@ const program = new commander.Command();
21
25
  // https://tldp.org/LDP/abs/html/exitcodes.html
22
26
  const SIGINT_EXIT_CODE = 130;
23
27
 
24
- async function logUncaughtError(e: mixed) {
25
- if (e instanceof ThrowableDiagnostic) {
26
- for (let diagnostic of e.diagnostics) {
27
- let {message, codeframe, stack, hints, documentation} =
28
- await prettyDiagnostic(diagnostic);
29
- INTERNAL_ORIGINAL_CONSOLE.error(chalk.red(message));
30
- if (codeframe || stack) {
31
- INTERNAL_ORIGINAL_CONSOLE.error('');
32
- }
33
- INTERNAL_ORIGINAL_CONSOLE.error(codeframe);
34
- INTERNAL_ORIGINAL_CONSOLE.error(stack);
35
- if ((stack || codeframe) && hints.length > 0) {
36
- INTERNAL_ORIGINAL_CONSOLE.error('');
37
- }
38
- for (let h of hints) {
39
- INTERNAL_ORIGINAL_CONSOLE.error(chalk.blue(h));
40
- }
41
- if (documentation) {
42
- INTERNAL_ORIGINAL_CONSOLE.error(chalk.magenta.bold(documentation));
43
- }
44
- }
45
- } else {
46
- INTERNAL_ORIGINAL_CONSOLE.error(e);
47
- }
48
-
49
- // A hack to definitely ensure we logged the uncaught exception
50
- await new Promise((resolve) => setTimeout(resolve, 100));
51
- }
52
-
53
- const handleUncaughtException = async (exception) => {
54
- try {
55
- await logUncaughtError(exception);
56
- } catch (err) {
57
- console.error(exception);
58
- console.error(err);
59
- }
60
-
61
- process.exit(1);
62
- };
63
-
64
28
  process.on('unhandledRejection', handleUncaughtException);
65
29
 
66
30
  program.storeOptionsAsProperties();
67
31
  program.version(version);
68
32
 
69
- // Only display choices available to callers OS
70
- let watcherBackendChoices = ['brute-force'];
71
- switch (process.platform) {
72
- case 'darwin': {
73
- watcherBackendChoices.push('watchman', 'fs-events');
74
- break;
75
- }
76
- case 'linux': {
77
- watcherBackendChoices.push('watchman', 'inotify');
78
- break;
79
- }
80
- case 'win32': {
81
- watcherBackendChoices.push('watchman', 'windows');
82
- break;
83
- }
84
- case 'freebsd' || 'openbsd': {
85
- watcherBackendChoices.push('watchman');
86
- break;
87
- }
88
- default:
89
- break;
90
- }
91
-
92
- // --no-cache, --cache-dir, --no-source-maps, --no-autoinstall, --global?, --public-url, --log-level
93
- // --no-content-hash, --experimental-scope-hoisting, --detailed-report
94
- const commonOptions = {
95
- '--no-cache': 'disable the filesystem cache',
96
- '--config <path>':
97
- 'specify which config to use. can be a path or a package name',
98
- '--cache-dir <path>': 'set the cache directory. defaults to ".parcel-cache"',
99
- '--watch-dir <path>':
100
- 'set the root watch directory. defaults to nearest lockfile or source control dir.',
101
- '--watch-ignore [path]': [
102
- `list of directories watcher should not be tracking for changes. defaults to ['.git', '.hg']`,
103
- (dirs) => dirs.split(','),
104
- ],
105
- '--watch-backend': new commander.Option(
106
- '--watch-backend <name>',
107
- 'set watcher backend',
108
- ).choices(watcherBackendChoices),
109
- '--no-source-maps': 'disable sourcemaps',
110
- '--target [name]': [
111
- 'only build given target(s)',
112
- (val, list) => list.concat([val]),
113
- [],
114
- ],
115
- '--log-level <level>': new commander.Option(
116
- '--log-level <level>',
117
- 'set the log level',
118
- ).choices(['none', 'error', 'warn', 'info', 'verbose']),
119
- '--dist-dir <dir>':
120
- 'output directory to write to when unspecified by targets',
121
- '--no-autoinstall': 'disable autoinstall',
122
- '--profile': 'enable sampling build profiling',
123
- '--trace': 'enable build tracing',
124
- '-V, --version': 'output the version number',
125
- '--detailed-report [count]': [
126
- 'print the asset timings and sizes in the build report',
127
- parseOptionInt,
128
- ],
129
- '--reporter <name>': [
130
- 'additional reporters to run',
131
- (val, acc) => {
132
- acc.push(val);
133
- return acc;
134
- },
135
- [],
136
- ],
137
- '--feature-flag <name=value>': [
138
- 'sets the value of a feature flag',
139
- (value, previousValue) => {
140
- let [name, val] = value.split('=');
141
- if (name in DEFAULT_FEATURE_FLAGS) {
142
- let featureFlagValue;
143
- if (typeof DEFAULT_FEATURE_FLAGS[name] === 'boolean') {
144
- if (val !== 'true' && val !== 'false') {
145
- throw new Error(
146
- `Feature flag ${name} must be set to true or false`,
147
- );
148
- }
149
- featureFlagValue = val === 'true';
150
- }
151
- previousValue[name] = featureFlagValue ?? String(val);
152
- } else {
153
- INTERNAL_ORIGINAL_CONSOLE.warn(
154
- `Unknown feature flag ${name} specified, it will be ignored`,
155
- );
156
- }
157
- return previousValue;
158
- },
159
- {},
160
- ],
161
- };
162
-
163
- var hmrOptions = {
164
- '--no-hmr': 'disable hot module replacement',
165
- '-p, --port <port>': [
166
- 'set the port to serve on. defaults to $PORT or 1234',
167
- process.env.PORT,
168
- ],
169
- '--host <host>':
170
- 'set the host to listen on, defaults to listening on all interfaces',
171
- '--https': 'serves files over HTTPS',
172
- '--cert <path>': 'path to certificate to use with HTTPS',
173
- '--key <path>': 'path to private key to use with HTTPS',
174
- '--hmr-port <port>': ['hot module replacement port', process.env.HMR_PORT],
175
- '--hmr-host <host>': ['hot module replacement host', process.env.HMR_HOST],
176
- };
177
-
178
- function applyOptions(cmd, options) {
179
- for (let opt in options) {
180
- const option = options[opt];
181
- if (option instanceof commander.Option) {
182
- cmd.addOption(option);
183
- } else {
184
- cmd.option(opt, ...(Array.isArray(option) ? option : [option]));
185
- }
186
- }
187
- }
188
-
189
33
  let serve = program
190
34
  .command('serve [input...]')
191
35
  .description('starts a development server')
@@ -232,92 +76,6 @@ let build = program
232
76
 
233
77
  applyOptions(build, commonOptions);
234
78
 
235
- function makeDebugCommand() {
236
- const debug = new commander.Command('debug').description(
237
- 'Debug commands for atlaspack',
238
- );
239
-
240
- const invalidate = debug
241
- .command('invalidate [input...]')
242
- .description('Run cache invalidation, then exit')
243
- .action(async (entries, opts, command: any) => {
244
- try {
245
- if (entries.length === 0) {
246
- entries = ['.'];
247
- }
248
- entries = entries.map((entry) => path.resolve(entry));
249
-
250
- Object.assign(command, opts);
251
- const fs = new NodeFS();
252
- const options = await normalizeOptions(command, fs);
253
-
254
- const Atlaspack = require('@atlaspack/core').default;
255
-
256
- const atlaspack = new Atlaspack({
257
- entries,
258
- defaultConfig: require.resolve('@atlaspack/config-default', {
259
- paths: [fs.cwd(), __dirname],
260
- }),
261
- shouldPatchConsole: false,
262
- ...options,
263
- shouldBuildLazily: true,
264
- watchBackend: 'watchman',
265
- });
266
- console.log('Created atlaspack instance');
267
-
268
- await atlaspack.unstable_invalidate();
269
- console.log('Done invalidating cache');
270
- } catch (err) {
271
- handleUncaughtException(err);
272
- }
273
- });
274
- applyOptions(invalidate, commonOptions);
275
-
276
- const buildAssetGraph = debug
277
- .command('build-asset-graph [input...]')
278
- .description('Build the asset graph then exit')
279
- .action(async (entries, opts, command: any) => {
280
- try {
281
- if (entries.length === 0) {
282
- entries = ['.'];
283
- }
284
- entries = entries.map((entry) => path.resolve(entry));
285
-
286
- Object.assign(command, opts);
287
- const fs = new NodeFS();
288
- const options = await normalizeOptions(command, fs);
289
-
290
- const Atlaspack = require('@atlaspack/core').default;
291
-
292
- const atlaspack = new Atlaspack({
293
- entries,
294
- defaultConfig: require.resolve('@atlaspack/config-default', {
295
- paths: [fs.cwd(), __dirname],
296
- }),
297
- shouldPatchConsole: false,
298
- ...options,
299
- shouldBuildLazily: true,
300
- watchBackend: 'watchman',
301
- featureFlags: {
302
- ...options.featureFlags,
303
- fixQuadraticCacheInvalidation: 'NEW',
304
- useLmdbJsLite: true,
305
- },
306
- });
307
- console.log('Created atlaspack instance');
308
-
309
- await atlaspack.unstable_buildAssetGraph();
310
- console.log('Done building asset graph');
311
- process.exit(0);
312
- } catch (err) {
313
- handleUncaughtException(err);
314
- }
315
- });
316
- applyOptions(buildAssetGraph, commonOptions);
317
-
318
- return debug;
319
- }
320
-
321
79
  program.addCommand(makeDebugCommand());
322
80
 
323
81
  program
@@ -497,178 +255,3 @@ async function run(
497
255
  await exit();
498
256
  }
499
257
  }
500
-
501
- function parsePort(portValue: string): number {
502
- let parsedPort = Number(portValue);
503
-
504
- // Throw an error if port value is invalid...
505
- if (!Number.isInteger(parsedPort)) {
506
- throw new Error(`Port ${portValue} is not a valid integer.`);
507
- }
508
-
509
- return parsedPort;
510
- }
511
-
512
- function parseOptionInt(value) {
513
- const parsedValue = parseInt(value, 10);
514
- if (isNaN(parsedValue)) {
515
- throw new commander.InvalidOptionArgumentError('Must be an integer.');
516
- }
517
- return parsedValue;
518
- }
519
-
520
- function shouldUseProductionDefaults(command) {
521
- return command.name() === 'build' || command.production === true;
522
- }
523
-
524
- async function normalizeOptions(
525
- command,
526
- inputFS,
527
- ): Promise<InitialAtlaspackOptions> {
528
- let nodeEnv;
529
- if (shouldUseProductionDefaults(command)) {
530
- nodeEnv = process.env.NODE_ENV || 'production';
531
- // Autoinstall unless explicitly disabled or we detect a CI environment.
532
- command.autoinstall = !(command.autoinstall === false || process.env.CI);
533
- } else {
534
- nodeEnv = process.env.NODE_ENV || 'development';
535
- }
536
-
537
- // Set process.env.NODE_ENV to a default if undefined so that it is
538
- // available in JS configs and plugins.
539
- process.env.NODE_ENV = nodeEnv;
540
-
541
- let https = !!command.https;
542
- if (command.cert && command.key) {
543
- https = {
544
- cert: command.cert,
545
- key: command.key,
546
- };
547
- }
548
-
549
- let serveOptions = false;
550
- let {host} = command;
551
-
552
- // Ensure port is valid and available
553
- let port = parsePort(command.port || '1234');
554
- let originalPort = port;
555
- if (
556
- !shouldUseProductionDefaults(command) &&
557
- (command.name() === 'serve' || command.hmr)
558
- ) {
559
- try {
560
- port = await getPort({port, host});
561
- } catch (err) {
562
- throw new ThrowableDiagnostic({
563
- diagnostic: {
564
- message: `Could not get available port: ${err.message}`,
565
- origin: 'atlaspack',
566
- stack: err.stack,
567
- },
568
- });
569
- }
570
-
571
- if (port !== originalPort) {
572
- let errorMessage = `Port "${originalPort}" could not be used`;
573
- if (command.port != null) {
574
- // Throw the error if the user defined a custom port
575
- throw new Error(errorMessage);
576
- } else {
577
- // Atlaspack logger is not set up at this point, so just use native INTERNAL_ORIGINAL_CONSOLE
578
- INTERNAL_ORIGINAL_CONSOLE.warn(errorMessage);
579
- }
580
- }
581
- }
582
-
583
- if (command.name() === 'serve') {
584
- let {publicUrl} = command;
585
-
586
- serveOptions = {
587
- https,
588
- port,
589
- host,
590
- publicUrl,
591
- };
592
- }
593
-
594
- let hmrOptions = null;
595
- if (!shouldUseProductionDefaults(command) && command.hmr !== false) {
596
- let hmrport = command.hmrPort ? parsePort(command.hmrPort) : port;
597
- let hmrhost = command.hmrHost ? command.hmrHost : host;
598
-
599
- hmrOptions = {
600
- port: hmrport,
601
- host: hmrhost,
602
- };
603
- }
604
-
605
- if (command.detailedReport === true) {
606
- command.detailedReport = '10';
607
- }
608
-
609
- let additionalReporters = [
610
- {packageName: '@atlaspack/reporter-cli', resolveFrom: __filename},
611
- ...(command.reporter: Array<string>).map((packageName) => ({
612
- packageName,
613
- resolveFrom: path.join(inputFS.cwd(), 'index'),
614
- })),
615
- ];
616
-
617
- if (command.trace) {
618
- additionalReporters.unshift({
619
- packageName: '@atlaspack/reporter-tracer',
620
- resolveFrom: __filename,
621
- });
622
- }
623
-
624
- let mode = shouldUseProductionDefaults(command)
625
- ? 'production'
626
- : 'development';
627
-
628
- const normalizeIncludeExcludeList = (input?: string): string[] => {
629
- if (typeof input !== 'string') return [];
630
- return input.split(',').map((value) => value.trim());
631
- };
632
-
633
- return {
634
- shouldDisableCache: command.cache === false,
635
- cacheDir: command.cacheDir,
636
- watchDir: command.watchDir,
637
- watchBackend: command.watchBackend,
638
- watchIgnore: command.watchIgnore,
639
- config: command.config,
640
- mode,
641
- hmrOptions,
642
- shouldContentHash: hmrOptions ? false : command.contentHash,
643
- serveOptions,
644
- targets: command.target.length > 0 ? command.target : null,
645
- shouldAutoInstall: command.autoinstall ?? true,
646
- logLevel: command.logLevel,
647
- shouldProfile: command.profile,
648
- shouldTrace: command.trace,
649
- shouldBuildLazily: typeof command.lazy !== 'undefined',
650
- lazyIncludes: normalizeIncludeExcludeList(command.lazy),
651
- lazyExcludes: normalizeIncludeExcludeList(command.lazyExclude),
652
- shouldBundleIncrementally:
653
- process.env.ATLASPACK_INCREMENTAL_BUNDLING === 'false' ? false : true,
654
- detailedReport:
655
- command.detailedReport != null
656
- ? {
657
- assetsPerBundle: parseInt(command.detailedReport, 10),
658
- }
659
- : null,
660
- env: {
661
- NODE_ENV: nodeEnv,
662
- },
663
- additionalReporters,
664
- defaultTargetOptions: {
665
- shouldOptimize:
666
- command.optimize != null ? command.optimize : mode === 'production',
667
- sourceMaps: command.sourceMaps ?? true,
668
- shouldScopeHoist: command.scopeHoist,
669
- publicUrl: command.publicUrl,
670
- distDir: command.distDir,
671
- },
672
- featureFlags: command.featureFlag,
673
- };
674
- }
@@ -0,0 +1,46 @@
1
+ // @flow strict-local
2
+
3
+ import ThrowableDiagnostic from '@atlaspack/diagnostic';
4
+ import {prettyDiagnostic} from '@atlaspack/utils';
5
+ import {INTERNAL_ORIGINAL_CONSOLE} from '@atlaspack/logger';
6
+ import chalk from 'chalk';
7
+
8
+ export async function logUncaughtError(e: mixed) {
9
+ if (e instanceof ThrowableDiagnostic) {
10
+ for (let diagnostic of e.diagnostics) {
11
+ let {message, codeframe, stack, hints, documentation} =
12
+ await prettyDiagnostic(diagnostic);
13
+ INTERNAL_ORIGINAL_CONSOLE.error(chalk.red(message));
14
+ if (codeframe || stack) {
15
+ INTERNAL_ORIGINAL_CONSOLE.error('');
16
+ }
17
+ INTERNAL_ORIGINAL_CONSOLE.error(codeframe);
18
+ INTERNAL_ORIGINAL_CONSOLE.error(stack);
19
+ if ((stack || codeframe) && hints.length > 0) {
20
+ INTERNAL_ORIGINAL_CONSOLE.error('');
21
+ }
22
+ for (let h of hints) {
23
+ INTERNAL_ORIGINAL_CONSOLE.error(chalk.blue(h));
24
+ }
25
+ if (documentation) {
26
+ INTERNAL_ORIGINAL_CONSOLE.error(chalk.magenta.bold(documentation));
27
+ }
28
+ }
29
+ } else {
30
+ INTERNAL_ORIGINAL_CONSOLE.error(e);
31
+ }
32
+
33
+ // A hack to definitely ensure we logged the uncaught exception
34
+ await new Promise((resolve) => setTimeout(resolve, 100));
35
+ }
36
+
37
+ export async function handleUncaughtException(exception: mixed) {
38
+ try {
39
+ await logUncaughtError(exception);
40
+ } catch (err) {
41
+ console.error(exception);
42
+ console.error(err);
43
+ }
44
+
45
+ process.exit(1);
46
+ }
@@ -0,0 +1,99 @@
1
+ // @flow strict-local
2
+
3
+ import {NodeFS} from '@atlaspack/fs';
4
+ import commander, {type commander$Command} from 'commander';
5
+ import path from 'path';
6
+ import {normalizeOptions, type Options} from './normalizeOptions';
7
+ import type {CommandExt} from './normalizeOptions';
8
+ import {applyOptions} from './applyOptions';
9
+ import {commonOptions} from './options';
10
+ import {handleUncaughtException} from './handleUncaughtException';
11
+
12
+ export function makeDebugCommand(): commander$Command {
13
+ const debug = new commander.Command('debug').description(
14
+ 'Debug commands for atlaspack',
15
+ );
16
+
17
+ const invalidate = debug
18
+ .command('invalidate [input...]')
19
+ .description('Run cache invalidation, then exit')
20
+ .action(async (args: string[], opts: Options, command: CommandExt) => {
21
+ try {
22
+ let entries = args;
23
+ if (entries.length === 0) {
24
+ entries = ['.'];
25
+ }
26
+ entries = entries.map((entry) => path.resolve(entry));
27
+ Object.assign(command, opts);
28
+
29
+ const fs = new NodeFS();
30
+ const options = await normalizeOptions(command, fs);
31
+
32
+ const Atlaspack = require('@atlaspack/core').default;
33
+
34
+ const atlaspack = new Atlaspack({
35
+ entries,
36
+ defaultConfig: require.resolve('@atlaspack/config-default', {
37
+ paths: [fs.cwd(), __dirname],
38
+ }),
39
+ shouldPatchConsole: false,
40
+ ...options,
41
+ shouldBuildLazily: true,
42
+ watchBackend: 'watchman',
43
+ });
44
+ console.log('Created atlaspack instance');
45
+
46
+ await atlaspack.unstable_invalidate();
47
+ console.log('Done invalidating cache');
48
+ } catch (err) {
49
+ handleUncaughtException(err);
50
+ }
51
+ });
52
+ applyOptions(invalidate, commonOptions);
53
+
54
+ const buildAssetGraph = debug
55
+ .command('build-asset-graph [input...]')
56
+ .description('Build the asset graph then exit')
57
+ .action(async (args: string[], opts: Options, command: CommandExt) => {
58
+ try {
59
+ let entries = args;
60
+
61
+ if (entries.length === 0) {
62
+ entries = ['.'];
63
+ }
64
+ entries = entries.map((entry) => path.resolve(entry));
65
+
66
+ Object.assign(command, opts);
67
+ const fs = new NodeFS();
68
+ const options = await normalizeOptions(command, fs);
69
+
70
+ const Atlaspack = require('@atlaspack/core').default;
71
+
72
+ const atlaspack = new Atlaspack({
73
+ entries,
74
+ defaultConfig: require.resolve('@atlaspack/config-default', {
75
+ paths: [fs.cwd(), __dirname],
76
+ }),
77
+ shouldPatchConsole: false,
78
+ ...options,
79
+ shouldBuildLazily: true,
80
+ watchBackend: 'watchman',
81
+ featureFlags: {
82
+ ...options.featureFlags,
83
+ fixQuadraticCacheInvalidation: 'NEW',
84
+ useLmdbJsLite: true,
85
+ },
86
+ });
87
+ console.log('Created atlaspack instance');
88
+
89
+ await atlaspack.unstable_buildAssetGraph();
90
+ console.log('Done building asset graph');
91
+ process.exit(0);
92
+ } catch (err) {
93
+ handleUncaughtException(err);
94
+ }
95
+ });
96
+ applyOptions(buildAssetGraph, commonOptions);
97
+
98
+ return debug;
99
+ }