Convert CLI top-level imports as dynamic imports (#7635)

This commit is contained in:
Bjorn Lu 2023-07-13 22:34:59 +08:00 committed by GitHub
parent db4095d3f5
commit bdde6b9f6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 46 deletions

View file

@ -22,6 +22,7 @@ import { printHelp } from '../../core/messages.js';
import { appendForwardSlash } from '../../core/path.js';
import { apply as applyPolyfill } from '../../core/polyfill.js';
import { parseNpmName } from '../../core/util.js';
import { eventCliSession, telemetry } from '../../events/index.js';
import { generate, parse, t, visit } from './babel.js';
import { ensureImport } from './imports.js';
import { wrapDefaultExport } from './wrapper.js';
@ -29,7 +30,6 @@ import { wrapDefaultExport } from './wrapper.js';
interface AddOptions {
logging: LogOptions;
flags: yargs.Arguments;
cwd?: string;
}
interface IntegrationInfo {
@ -86,7 +86,8 @@ async function getRegistry(): Promise<string> {
}
}
export async function add(names: string[], { cwd, flags, logging }: AddOptions) {
export async function add(names: string[], { flags, logging }: AddOptions) {
telemetry.record(eventCliSession('add'));
applyPolyfill();
if (flags.help || names.length === 0) {
printHelp({
@ -128,6 +129,7 @@ export async function add(names: string[], { cwd, flags, logging }: AddOptions)
}
// Some packages might have a common alias! We normalize those here.
const cwd = flags.root;
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
const integrations = await validateIntegrations(integrationNames);
let installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logging });

View file

@ -2,15 +2,8 @@
import * as colors from 'kleur/colors';
import yargs from 'yargs-parser';
import { ASTRO_VERSION } from '../core/constants.js';
import { collectErrorMetadata } from '../core/errors/dev/index.js';
import { createSafeError } from '../core/errors/index.js';
import { debug, type LogOptions } from '../core/logger/core.js';
import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js';
import { formatErrorMessage, printHelp } from '../core/messages.js';
import * as event from '../events/index.js';
import { eventError, telemetry } from '../events/index.js';
import type { LogOptions } from '../core/logger/core.js';
type Arguments = yargs.Arguments;
type CLICommand =
| 'help'
| 'version'
@ -25,7 +18,8 @@ type CLICommand =
| 'telemetry';
/** Display --help flag */
function printAstroHelp() {
async function printAstroHelp() {
const { printHelp } = await import('../core/messages.js');
printHelp({
commandName: 'astro',
usage: '[command] [...flags]',
@ -63,7 +57,7 @@ function printVersion() {
}
/** Determine which command the user requested */
function resolveCommand(flags: Arguments): CLICommand {
function resolveCommand(flags: yargs.Arguments): CLICommand {
const cmd = flags._[2] as string;
if (flags.version) return 'version';
@ -90,23 +84,20 @@ function resolveCommand(flags: Arguments): CLICommand {
* to present user-friendly error output where the fn is called.
**/
async function runCommand(cmd: string, flags: yargs.Arguments) {
const root = flags.root;
// These commands can run directly without parsing the user config.
switch (cmd) {
case 'help':
printAstroHelp();
await printAstroHelp();
return;
case 'version':
printVersion();
return;
case 'info': {
const { printInfo } = await import('./info/index.js');
await printInfo({ cwd: root, flags });
await printInfo({ flags });
return;
}
case 'docs': {
telemetry.record(event.eventCliSession(cmd));
const { docs } = await import('./docs/index.js');
await docs({ flags });
return;
@ -121,6 +112,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
}
}
const { enableVerboseLogging, nodeLogDestination } = await import('../core/logger/node.js');
const logging: LogOptions = {
dest: nodeLogDestination,
level: 'info',
@ -141,10 +133,9 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
// by the end of this switch statement.
switch (cmd) {
case 'add': {
telemetry.record(event.eventCliSession(cmd));
const { add } = await import('./add/index.js');
const packages = flags._.slice(3) as string[];
await add(packages, { cwd: root, flags, logging });
await add(packages, { flags, logging });
return;
}
case 'dev': {
@ -177,7 +168,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
await checkServer.watch();
return await new Promise(() => {}); // lives forever
} else {
let checkResult = await checkServer.check();
const checkResult = await checkServer.check();
return process.exit(checkResult);
}
}
@ -201,29 +192,7 @@ export async function cli(args: string[]) {
try {
await runCommand(cmd, flags);
} catch (err) {
const { throwAndExit } = await import('./throw-and-exit.js');
await throwAndExit(cmd, err);
}
}
/** Display error and exit */
async function throwAndExit(cmd: string, err: unknown) {
let telemetryPromise: Promise<any>;
let errorMessage: string;
function exitWithErrorMessage() {
console.error(errorMessage);
process.exit(1);
}
const errorWithMetadata = collectErrorMetadata(createSafeError(err));
telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
errorMessage = formatErrorMessage(errorWithMetadata);
// Timeout the error reporter (very short) because the user is waiting.
// NOTE(fks): It is better that we miss some events vs. holding too long.
// TODO(fks): Investigate using an AbortController once we drop Node v14.
setTimeout(exitWithErrorMessage, 400);
// Wait for the telemetry event to send, then exit. Ignore any error.
await telemetryPromise
.catch((err2) => debug('telemetry', `record() error: ${err2.message}`))
.then(exitWithErrorMessage);
}

View file

@ -7,11 +7,10 @@ import { openConfig } from '../../core/config/index.js';
import { ASTRO_VERSION } from '../../core/constants.js';
interface InfoOptions {
cwd?: string;
flags: yargs.Arguments;
}
export async function printInfo({ cwd, flags }: InfoOptions) {
export async function printInfo({ flags }: InfoOptions) {
const packageManager = await whichPm(process.cwd());
let adapter = "Couldn't determine.";
let integrations = [];
@ -24,7 +23,7 @@ export async function printInfo({ cwd, flags }: InfoOptions) {
try {
const { userConfig } = await openConfig({
cwd,
cwd: flags.root,
flags,
cmd: 'info',
});

View file

@ -0,0 +1,29 @@
/* eslint-disable no-console */
import { collectErrorMetadata } from '../core/errors/dev/index.js';
import { createSafeError } from '../core/errors/index.js';
import { debug } from '../core/logger/core.js';
import { formatErrorMessage } from '../core/messages.js';
import { eventError, telemetry } from '../events/index.js';
/** Display error and exit */
export async function throwAndExit(cmd: string, err: unknown) {
let telemetryPromise: Promise<any>;
let errorMessage: string;
function exitWithErrorMessage() {
console.error(errorMessage);
process.exit(1);
}
const errorWithMetadata = collectErrorMetadata(createSafeError(err));
telemetryPromise = telemetry.record(eventError({ cmd, err: errorWithMetadata, isFatal: true }));
errorMessage = formatErrorMessage(errorWithMetadata);
// Timeout the error reporter (very short) because the user is waiting.
// NOTE(fks): It is better that we miss some events vs. holding too long.
// TODO(fks): Investigate using an AbortController once we drop Node v14.
setTimeout(exitWithErrorMessage, 400);
// Wait for the telemetry event to send, then exit. Ignore any error.
await telemetryPromise
.catch((err2) => debug('telemetry', `record() error: ${err2.message}`))
.then(exitWithErrorMessage);
}