From fbe85b594059580db702cf7140d83b964111a230 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 7 Sep 2023 15:54:08 -0500 Subject: [PATCH 1/5] feat(create-astro): improve performance --- .changeset/ten-kings-smash.md | 5 +++++ packages/create-astro/create-astro.mjs | 2 +- packages/create-astro/package.json | 2 +- packages/create-astro/src/actions/context.ts | 12 +++++++----- packages/create-astro/src/actions/intro.ts | 14 ++++++-------- packages/create-astro/src/actions/next-steps.ts | 4 ++-- packages/create-astro/src/index.ts | 2 ++ packages/create-astro/src/messages.ts | 11 +++++------ 8 files changed, 29 insertions(+), 23 deletions(-) create mode 100644 .changeset/ten-kings-smash.md diff --git a/.changeset/ten-kings-smash.md b/.changeset/ten-kings-smash.md new file mode 100644 index 000000000000..28d98179ad05 --- /dev/null +++ b/.changeset/ten-kings-smash.md @@ -0,0 +1,5 @@ +--- +'create-astro': minor +--- + +Improve startup performance by lazily initializing async contextual values diff --git a/packages/create-astro/create-astro.mjs b/packages/create-astro/create-astro.mjs index b7489a6b173d..50f446854c69 100755 --- a/packages/create-astro/create-astro.mjs +++ b/packages/create-astro/create-astro.mjs @@ -4,7 +4,7 @@ const currentVersion = process.versions.node; const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10); -const minimumMajorVersion = 14; +const minimumMajorVersion = 16; if (requiredMajorVersion < minimumMajorVersion) { console.error(`Node.js v${currentVersion} is out of date and unsupported!`); diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 0eb08cdc755c..6c24dec21aa0 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -31,7 +31,7 @@ "//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", + "@astrojs/cli-kit": "^0.2.5", "execa": "^8.0.1", "giget": "1.1.2", "node-fetch-native": "^1.4.0", diff --git a/packages/create-astro/src/actions/context.ts b/packages/create-astro/src/actions/context.ts index c91a0caae48c..7487823a7d4c 100644 --- a/packages/create-astro/src/actions/context.ts +++ b/packages/create-astro/src/actions/context.ts @@ -1,4 +1,5 @@ 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'; @@ -10,8 +11,8 @@ export interface Context { prompt: typeof prompt; cwd: string; packageManager: string; - username: string; - version: string; + username: Promise; + version: Promise; skipHouston: boolean; fancy?: boolean; dryRun?: boolean; @@ -25,6 +26,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 { @@ -52,7 +54,6 @@ export async function getContext(argv: string[]): Promise { ); const packageManager = detectPackageManager()?.name ?? 'npm'; - const [username, version] = await Promise.all([getName(), getVersion()]); let cwd = flags['_'][0]; let { '--help': help = false, @@ -86,14 +87,15 @@ export async function getContext(argv: string[]): Promise { help, prompt, packageManager, - username, - version, + username: getName(), + version: getVersion(), skipHouston, fancy, dryRun, projectName, template, ref: ref ?? 'latest', + hat: fancy ? random(['๐ŸŽฉ', '๐ŸŽฉ', '๐ŸŽฉ', '๐ŸŽฉ', '๐ŸŽ“', '๐Ÿ‘‘', '๐Ÿงข', '๐Ÿฆ']) : undefined, yes, install: install ?? (noInstall ? false : undefined), git: git ?? (noGit ? false : undefined), diff --git a/packages/create-astro/src/actions/intro.ts b/packages/create-astro/src/actions/intro.ts index a96c8e4346e6..25a348b48974 100644 --- a/packages/create-astro/src/actions/intro.ts +++ b/packages/create-astro/src/actions/intro.ts @@ -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) { +export async function intro(ctx: Pick) { + 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}!`, + ctx.version.then(version => ((version ? color.green(`v${version}`) : '') + ',')), + ctx.username.then(username => `${username}!`), ], random(welcome), ], - { hat } + { clear: true, hat: ctx.hat } ); - await banner(ctx.version); - } else { - await banner(ctx.version); } } diff --git a/packages/create-astro/src/actions/next-steps.ts b/packages/create-astro/src/actions/next-steps.ts index c79a80525428..ac69b7e9407a 100644 --- a/packages/create-astro/src/actions/next-steps.ts +++ b/packages/create-astro/src/actions/next-steps.ts @@ -3,7 +3,7 @@ import type { Context } from './context'; import { nextSteps, say } from '../messages.js'; -export async function next(ctx: Pick) { +export async function next(ctx: Pick) { let projectDir = path.relative(process.cwd(), ctx.cwd); const commandMap: { [key: string]: string } = { @@ -17,7 +17,7 @@ export async function next(ctx: Pick }); 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.')}`); From b20a0dd68fc94f89b9aa873d71ebcbf16bc6281c Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 7 Sep 2023 16:06:02 -0500 Subject: [PATCH 2/5] test: fix test by wrapping promise values --- packages/create-astro/src/actions/intro.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-astro/src/actions/intro.ts b/packages/create-astro/src/actions/intro.ts index 25a348b48974..9b2621ed85d9 100644 --- a/packages/create-astro/src/actions/intro.ts +++ b/packages/create-astro/src/actions/intro.ts @@ -14,8 +14,8 @@ export async function intro(ctx: Pick ((version ? color.green(`v${version}`) : '') + ',')), - ctx.username.then(username => `${username}!`), + Promise.resolve(ctx.version).then(version => ((version ? color.green(`v${version}`) : '') + ',')), + Promise.resolve(ctx.username).then(username => `${username}!`), ], random(welcome), ], From fcc9f03340d55141860bdb94f1cfc45af74a6480 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 7 Sep 2023 16:15:24 -0500 Subject: [PATCH 3/5] chore: remove uneeded deps --- packages/create-astro/create-astro.mjs | 2 +- packages/create-astro/package.json | 6 +----- packages/create-astro/src/actions/context.ts | 12 +++++++++--- packages/create-astro/src/actions/verify.ts | 1 - packages/create-astro/src/messages.ts | 9 +++------ 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/create-astro/create-astro.mjs b/packages/create-astro/create-astro.mjs index 50f446854c69..f9df779d871c 100755 --- a/packages/create-astro/create-astro.mjs +++ b/packages/create-astro/create-astro.mjs @@ -4,7 +4,7 @@ const currentVersion = process.versions.node; const requiredMajorVersion = parseInt(currentVersion.split('.')[0], 10); -const minimumMajorVersion = 16; +const minimumMajorVersion = 18; if (requiredMajorVersion < minimumMajorVersion) { console.error(`Node.js v${currentVersion} is out of date and unsupported!`); diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 6c24dec21aa0..b9641b1d5b20 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -32,13 +32,9 @@ "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES", "dependencies": { "@astrojs/cli-kit": "^0.2.5", - "execa": "^8.0.1", - "giget": "1.1.2", - "node-fetch-native": "^1.4.0", - "which-pm-runs": "^1.1.0" + "giget": "1.1.2" }, "devDependencies": { - "@types/which-pm-runs": "^1.0.0", "arg": "^5.0.2", "astro-scripts": "workspace:*", "chai": "^4.3.7", diff --git a/packages/create-astro/src/actions/context.ts b/packages/create-astro/src/actions/context.ts index 7487823a7d4c..ae720a1b3cd6 100644 --- a/packages/create-astro/src/actions/context.ts +++ b/packages/create-astro/src/actions/context.ts @@ -2,7 +2,6 @@ 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'; @@ -53,7 +52,7 @@ export async function getContext(argv: string[]): Promise { { argv, permissive: true } ); - const packageManager = detectPackageManager()?.name ?? 'npm'; + const packageManager = detectPackageManager() ?? 'npm'; let cwd = flags['_'][0]; let { '--help': help = false, @@ -88,7 +87,7 @@ export async function getContext(argv: string[]): Promise { prompt, packageManager, username: getName(), - version: getVersion(), + version: getVersion(packageManager), skipHouston, fancy, dryRun, @@ -107,3 +106,10 @@ export async function getContext(argv: string[]): Promise { }; 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; +} diff --git a/packages/create-astro/src/actions/verify.ts b/packages/create-astro/src/actions/verify.ts index 73359142bdb6..2df256ae9c0a 100644 --- a/packages/create-astro/src/actions/verify.ts +++ b/packages/create-astro/src/actions/verify.ts @@ -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'; diff --git a/packages/create-astro/src/messages.ts b/packages/create-astro/src/messages.ts index 94e4c1aa49ca..7e276308ef9e 100644 --- a/packages/create-astro/src/messages.ts +++ b/packages/create-astro/src/messages.ts @@ -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 { - const packageManager = detectPackageManager()?.name || 'npm'; +async function getRegistry(packageManager: string): Promise { try { const { stdout } = await shell(packageManager, ['config', 'get', 'registry']); return stdout?.trim()?.replace(/\/$/, '') || 'https://registry.npmjs.org'; @@ -78,10 +75,10 @@ export const getName = () => }); let v: string; -export const getVersion = () => +export const getVersion = (packageManager: string) => new Promise(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: '' }) From 86731548b966ec88a0f6152437c7ad36c1531b3c Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 7 Sep 2023 16:16:11 -0500 Subject: [PATCH 4/5] Update ten-kings-smash.md --- .changeset/ten-kings-smash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/ten-kings-smash.md b/.changeset/ten-kings-smash.md index 28d98179ad05..8dd84325711e 100644 --- a/.changeset/ten-kings-smash.md +++ b/.changeset/ten-kings-smash.md @@ -2,4 +2,4 @@ 'create-astro': minor --- -Improve startup performance by lazily initializing async contextual values +Improve startup performance by removing dependencies, lazily initializing async contextual values From 8a35fb84d4589a94181ae18e7e4e3102dd50f3f1 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Wed, 13 Sep 2023 09:14:57 -0500 Subject: [PATCH 5/5] chore: update lockfile --- pnpm-lock.yaml | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c005fdc9e81c..470bd046b480 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3566,24 +3566,12 @@ importers: packages/create-astro: dependencies: '@astrojs/cli-kit': - specifier: ^0.2.3 - version: 0.2.3 - execa: - specifier: ^8.0.1 - version: 8.0.1 + specifier: ^0.2.5 + version: 0.2.5 giget: specifier: 1.1.2 version: 1.1.2 - node-fetch-native: - specifier: ^1.4.0 - version: 1.4.0 - which-pm-runs: - specifier: ^1.1.0 - version: 1.1.0 devDependencies: - '@types/which-pm-runs': - specifier: ^1.0.0 - version: 1.0.0 arg: specifier: ^5.0.2 version: 5.0.2 @@ -5188,10 +5176,10 @@ packages: - prettier-plugin-astro dev: true - /@astrojs/cli-kit@0.2.3: - resolution: {integrity: sha512-MjB42mpIG/F2rFtdp4f3NylFCILuFSib2yITSq65fRaDFn8+UC8EMh6T7Jr3YqHAbUY5r8V8QWNgH4keOEO2BA==} + /@astrojs/cli-kit@0.2.5: + resolution: {integrity: sha512-j6zpNUjtHJGEIKkTrTPvQD3G/sJUKyseJty42iVR3HqytzqHwLK165vptdT4NZKfZ082yLnUtsOXxRyIdfm/AQ==} dependencies: - chalk: 5.2.0 + chalk: 5.3.0 log-update: 5.0.1 sisteransi: 1.0.5 dev: false @@ -10256,11 +10244,6 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 - /chalk@5.2.0: - resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false - /chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}