Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve create-astro startup performance #8456

Merged
merged 5 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ten-kings-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'create-astro': minor
---

Improve startup performance by removing dependencies, lazily initializing async contextual values
2 changes: 1 addition & 1 deletion packages/create-astro/create-astro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

const currentVersion = process.versions.node;
const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10);
const minimumMajorVersion = 14;
const minimumMajorVersion = 18;

if (requiredMajorVersion < minimumMajorVersion) {
console.error(`Node.js v${currentVersion} is out of date and unsupported!`);
Expand Down
8 changes: 2 additions & 6 deletions packages/create-astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@
"//a": "MOST PACKAGES SHOULD GO IN DEV_DEPENDENCIES! THEY WILL BE BUNDLED.",
"//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES",
"dependencies": {
"@astrojs/cli-kit": "^0.2.3",
"execa": "^8.0.1",
"giget": "1.1.2",
"node-fetch-native": "^1.4.0",
"which-pm-runs": "^1.1.0"
"@astrojs/cli-kit": "^0.2.5",
"giget": "1.1.2"
},
"devDependencies": {
"@types/which-pm-runs": "^1.0.0",
"arg": "^5.0.2",
"astro-scripts": "workspace:*",
"chai": "^4.3.7",
Expand Down
22 changes: 15 additions & 7 deletions packages/create-astro/src/actions/context.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { prompt } from '@astrojs/cli-kit';
import { random } from '@astrojs/cli-kit/utils';
import arg from 'arg';
import os from 'node:os';
import detectPackageManager from 'which-pm-runs';

import { getName, getVersion } from '../messages.js';

Expand All @@ -10,8 +10,8 @@ export interface Context {
prompt: typeof prompt;
cwd: string;
packageManager: string;
username: string;
version: string;
username: Promise<string>;
version: Promise<string>;
skipHouston: boolean;
fancy?: boolean;
dryRun?: boolean;
Expand All @@ -25,6 +25,7 @@ export interface Context {
stdin?: typeof process.stdin;
stdout?: typeof process.stdout;
exit(code: number): never;
hat?: string;
}

export async function getContext(argv: string[]): Promise<Context> {
Expand All @@ -51,8 +52,7 @@ export async function getContext(argv: string[]): Promise<Context> {
{ argv, permissive: true }
);

const packageManager = detectPackageManager()?.name ?? 'npm';
const [username, version] = await Promise.all([getName(), getVersion()]);
const packageManager = detectPackageManager() ?? 'npm';
let cwd = flags['_'][0];
let {
'--help': help = false,
Expand Down Expand Up @@ -86,14 +86,15 @@ export async function getContext(argv: string[]): Promise<Context> {
help,
prompt,
packageManager,
username,
version,
username: getName(),
version: getVersion(packageManager),
skipHouston,
fancy,
dryRun,
projectName,
template,
ref: ref ?? 'latest',
hat: fancy ? random(['🎩', '🎩', '🎩', '🎩', '🎓', '👑', '🧢', '🍦']) : undefined,
yes,
install: install ?? (noInstall ? false : undefined),
git: git ?? (noGit ? false : undefined),
Expand All @@ -105,3 +106,10 @@ export async function getContext(argv: string[]): Promise<Context> {
};
return context;
}

function detectPackageManager() {
if (!process.env.npm_config_user_agent) return;
const specifier = process.env.npm_config_user_agent.split(' ')[0];
const name = specifier.substring(0, specifier.lastIndexOf('/'));
return name === 'npminstall' ? 'cnpm' : name;
}
14 changes: 6 additions & 8 deletions packages/create-astro/src/actions/intro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@ import { color, label } from '@astrojs/cli-kit';
import { random } from '@astrojs/cli-kit/utils';
import { banner, say, welcome } from '../messages.js';

export async function intro(ctx: Pick<Context, 'skipHouston' | 'version' | 'username' | 'fancy'>) {
export async function intro(ctx: Pick<Context, 'hat' | 'skipHouston' | 'version' | 'username' | 'fancy'>) {
banner();

if (!ctx.skipHouston) {
const hat = ctx.fancy ? random(['🎩', '🎩', '👑', '🧢', '🍦']) : undefined;
await say(
[
[
'Welcome',
'to',
label('astro', color.bgGreen, color.black),
(ctx.version ? color.green(`v${ctx.version}`) : '') + ',',
`${ctx.username}!`,
Promise.resolve(ctx.version).then(version => ((version ? color.green(`v${version}`) : '') + ',')),
Promise.resolve(ctx.username).then(username => `${username}!`),
],
random(welcome),
],
{ hat }
{ clear: true, hat: ctx.hat }
);
await banner(ctx.version);
} else {
await banner(ctx.version);
}
}
4 changes: 2 additions & 2 deletions packages/create-astro/src/actions/next-steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Context } from './context';

import { nextSteps, say } from '../messages.js';

export async function next(ctx: Pick<Context, 'cwd' | 'packageManager' | 'skipHouston'>) {
export async function next(ctx: Pick<Context, 'hat' | 'cwd' | 'packageManager' | 'skipHouston'>) {
let projectDir = path.relative(process.cwd(), ctx.cwd);

const commandMap: { [key: string]: string } = {
Expand All @@ -17,7 +17,7 @@ export async function next(ctx: Pick<Context, 'cwd' | 'packageManager' | 'skipHo
await nextSteps({ projectDir, devCmd });

if (!ctx.skipHouston) {
await say(['Good luck out there, astronaut! 🚀']);
await say(['Good luck out there, astronaut! 🚀'], { hat: ctx.hat });
}
return;
}
1 change: 0 additions & 1 deletion packages/create-astro/src/actions/verify.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Context } from './context';

import { color } from '@astrojs/cli-kit';
import fetch from 'node-fetch-native';
import dns from 'node:dns/promises';
import { bannerAbort, error, info, log } from '../messages.js';
import { getTemplateTarget } from './template.js';
Expand Down
2 changes: 2 additions & 0 deletions packages/create-astro/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ process.on('SIGTERM', exit);
// https://github.com/withastro/docs/blob/main/src/pages/en/install/auto.md
// if you make any changes to the flow or wording here.
export async function main() {
// Clear console because PNPM startup is super ugly
console.clear();
ematipico marked this conversation as resolved.
Show resolved Hide resolved
// NOTE: In the v7.x version of npm, the default behavior of `npm init` was changed
// to no longer require `--` to pass args and instead pass `--` directly to us. This
// broke our arg parser, since `--` is a special kind of flag. Filtering for `--` here
Expand Down
20 changes: 8 additions & 12 deletions packages/create-astro/src/messages.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/* eslint no-console: 'off' */
import { color, say as houston, label, spinner as load } from '@astrojs/cli-kit';
import { align, sleep } from '@astrojs/cli-kit/utils';
import fetch from 'node-fetch-native';
import { exec } from 'node:child_process';
import stripAnsi from 'strip-ansi';
import detectPackageManager from 'which-pm-runs';
import { shell } from './shell.js';

// Users might lack access to the global npm registry, this function
// checks the user's project type and will return the proper npm registry
//
// A copy of this function also exists in the astro package
async function getRegistry(): Promise<string> {
const packageManager = detectPackageManager()?.name || 'npm';
async function getRegistry(packageManager: string): Promise<string> {
try {
const { stdout } = await shell(packageManager, ['config', 'get', 'registry']);
return stdout?.trim()?.replace(/\/$/, '') || 'https://registry.npmjs.org';
Expand Down Expand Up @@ -78,10 +75,10 @@ export const getName = () =>
});

let v: string;
export const getVersion = () =>
export const getVersion = (packageManager: string) =>
new Promise<string>(async (resolve) => {
if (v) return resolve(v);
let registry = await getRegistry();
let registry = await getRegistry(packageManager);
const { version } = await fetch(`${registry}/astro/latest`, { redirect: 'follow' }).then(
(res) => res.json(),
() => ({ version: '' })
Expand All @@ -91,12 +88,11 @@ export const getVersion = () =>
});

export const log = (message: string) => stdout.write(message + '\n');
export const banner = async (version: string) =>
log(
`\n${label('astro', color.bgGreen, color.black)}${
version ? ' ' + color.green(color.bold(`v${version}`)) : ''
} ${color.bold('Launch sequence initiated.')}`
);
export const banner = () => {
const prefix = `astro`;
const suffix = `Launch sequence initiated.`;
log(`${label(prefix, color.bgGreen, color.black)} ${suffix}`);
}

export const bannerAbort = () =>
log(`\n${label('astro', color.bgRed)} ${color.bold('Launch sequence aborted.')}`);
Expand Down
27 changes: 5 additions & 22 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading