Skip to content

Commit

Permalink
feat(build): add vite-build-logger (#507)
Browse files Browse the repository at this point in the history
* feat(build): add vite-build-logger

* chore: fix types

* chore: fix logic

---------

Co-authored-by: Preston-Cook <[email protected]>
  • Loading branch information
doprz and Preston-Cook authored Feb 15, 2025
1 parent ee4c6ce commit 1aa4e8c
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/views/components/common/ScheduleListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ import {
RadioButton,
Trash,
} from '@phosphor-icons/react';
import { background } from '@shared/messages';
import type { UserSchedule } from '@shared/types/UserSchedule';
import Text from '@views/components/common/Text/Text';
import { useEnforceScheduleLimit } from '@views/hooks/useEnforceScheduleLimit';
import useSchedules from '@views/hooks/useSchedules';
import { LONGHORN_DEVELOPERS_ADMINS, LONGHORN_DEVELOPERS_SWE } from '@views/lib/getGitHubStats';
import clsx from 'clsx';
import React, { useEffect, useMemo, useState } from 'react';

import { Button } from './Button';
import DialogProvider, { usePrompt } from './DialogProvider/DialogProvider';
import { ExtensionRootWrapper, styleResetClass } from './ExtensionRoot/ExtensionRoot';
import Link from './Link';
import { SortableListDragHandle } from './SortableListDragHandle';

/**
Expand All @@ -32,6 +35,7 @@ interface ScheduleListItemProps {
}

const IS_STORYBOOK = import.meta.env.STORYBOOK;
const teamMembers = [...LONGHORN_DEVELOPERS_ADMINS, ...LONGHORN_DEVELOPERS_SWE];

/**
* This is a reusable dropdown component that can be used to toggle the visiblity of information
Expand All @@ -40,6 +44,7 @@ export default function ScheduleListItem({ schedule, onClick }: ScheduleListItem
const [activeSchedule] = useSchedules();
const [isEditing, setIsEditing] = useState(false);
const [editorValue, setEditorValue] = useState(schedule.name);
const teamMember = teamMembers[Math.floor(Math.random() * teamMembers.length)];

const showDialog = usePrompt();
const enforceScheduleLimit = useEnforceScheduleLimit();
Expand All @@ -65,13 +70,46 @@ export default function ScheduleListItem({ schedule, onClick }: ScheduleListItem
const handleBlur = async () => {
if (editorValue.trim() !== '' && editorValue.trim() !== schedule.name) {
schedule.name = (await renameSchedule(schedule.id, editorValue.trim())) as string;

if (schedule.name === '404') {
const url = chrome.runtime.getURL('/404.html');
background.openNewTab({ url });
}

if (Math.random() < 0.002) {
showDialog({
title: 'Schedule name already taken',
description: (
<>
<Text>Schedule name</Text>
<Text className='text-ut-burntorange'> {schedule.name} </Text>
<Text>
is already taken.
<br />
<br />
Join the&nbsp;
</Text>
<Link className='link' href='https://discord.gg/7pQDBGdmb7'>
<Text>Discord</Text>
</Link>
<Text> to contact {teamMember?.name as string}.</Text>
</>
),
// eslint-disable-next-line react/no-unstable-nested-components
buttons: close => (
<Button variant='minimal' color='ut-black' onClick={close}>
Go Back
</Button>
),
});
}
}
setIsEditing(false);
};

const handleDelete = () => {
showDialog({
title: `Are you sure?`,
title: 'Are you sure?',
description: (
<>
<Text>Deleting</Text>
Expand Down
81 changes: 81 additions & 0 deletions utils/plugins/vite-build-logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import chalk from 'chalk';
import type { Plugin } from 'vite';

/**
* Options to configure the build logger.
*/
interface BuildLoggerOptions {
includeEnvVars?: string[]; // Specific env vars to display
includeTimestamp?: boolean;
includeBuildTime?: boolean;
customMetadata?: Record<string, () => string | Promise<string>>;
}

/**
* Vite plugin to log build information.
*
* @param Options - to configure the build logger.
*
* @returns Vite plugin object.
*/
export function buildLogger(options: BuildLoggerOptions = {}): Plugin {
const startTime = Date.now();

return {
name: 'vite-build-logger',
enforce: 'post',

async closeBundle() {
console.log(`\n${chalk.bold.cyan('=== Build Information ===')}`);

// Environment
console.log(chalk.yellow('\nBuild Environment:'));
console.log(`🔧 Node Build Mode: ${process.env.NODE_ENV}`);
console.log(`🎯 Browser Target: ${process.env.BROWSER_TARGET}`);

// Timestamp
if (options.includeTimestamp) {
console.log(chalk.yellow('\nBuild Timestamp:'));
console.log(`📅 ${new Date().toISOString()}`);
}

// Build Time
if (options.includeBuildTime) {
const buildTime = Date.now() - startTime;
console.log(chalk.yellow('\nBuild Time:'));
console.log(`⏱️ ${buildTime}ms (${(buildTime / 1000).toFixed(2)}s)`);
}

// Selected Environment Variables
if (options.includeEnvVars?.length) {
console.log(chalk.yellow('\nEnvironment Variables:'));
for (const envVar of options.includeEnvVars) {
if (process.env[envVar]) {
// Mask sensitive variables that might contain tokens or keys
const isSensitive =
envVar.toLowerCase().includes('key') ||
envVar.toLowerCase().includes('token') ||
envVar.toLowerCase().includes('secret');

const value = isSensitive ? '****' : process.env[envVar];
console.log(`${envVar}: ${value}`);
} else {
console.log(`${envVar}: ${chalk.red('Not defined')}`);
}
}
}

// Custom Metadata
if (options.customMetadata) {
console.log(chalk.yellow('\nCustom Metadata:'));
for (const [key, getter] of Object.entries(options.customMetadata)) {
// eslint-disable-next-line no-await-in-loop
const value = await getter();
console.log(`${key}: ${value}`);
}
}

console.log(`\n${chalk.bold.cyan('=====================')}\n`);
},
};
}
30 changes: 30 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference types="vitest" />
import { crx } from '@crxjs/vite-plugin';
import react from '@vitejs/plugin-react-swc';
import { execSync } from 'child_process';
import { resolve } from 'path';
import UnoCSS from 'unocss/vite';
import Icons from 'unplugin-icons/vite';
Expand All @@ -11,17 +12,27 @@ import inspect from 'vite-plugin-inspect';
import packageJson from './package.json';
import manifest from './src/manifest';
import vitePluginRunCommandOnDemand from './utils/plugins/run-command-on-demand';
import { buildLogger } from './utils/plugins/vite-build-logger';

const BROWSER_TARGET = process.env.BROWSER_TARGET || 'chrome';

// Set browser target environment variable default
process.env.BROWSER_TARGET = BROWSER_TARGET;

const root = resolve(__dirname, 'src');
const pagesDir = resolve(root, 'pages');
const assetsDir = resolve(root, 'assets');
const publicDir = resolve(__dirname, 'public');

// Set default environment variables
process.env.PROD = process.env.NODE_ENV === 'production' ? 'true' : 'false';

const isBeta = !!process.env.BETA;
if (isBeta) {
process.env.VITE_BETA_BUILD = 'true';
}
process.env.VITE_PACKAGE_VERSION = packageJson.version;
// TODO: Debug this. If PROD is false, VITE_SENTRY_ENVIRONMENT is in production mode
if (process.env.PROD) {
process.env.VITE_SENTRY_ENVIRONMENT = 'production';
} else if (isBeta) {
Expand Down Expand Up @@ -162,6 +173,23 @@ export default defineConfig({
// afterServerStart: 'pnpm gulp forceDisableUseDynamicUrl',
closeBundle: 'pnpm gulp forceDisableUseDynamicUrl',
}),
buildLogger({
includeEnvVars: [
'VITE_PACKAGE_VERSION',
'NODE_ENV',
'BROWSER_TARGET',
'PROD',
'VITE_SENTRY_ENVIRONMENT',
'VITE_BETA_BUILD',
],
includeTimestamp: true,
includeBuildTime: true,
customMetadata: {
gitBranch: () => execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
gitCommit: () => execSync('git rev-parse --short HEAD').toString().trim(),
nodeVersion: () => process.version,
},
}),
],
resolve: {
alias: {
Expand Down Expand Up @@ -205,6 +233,8 @@ export default defineConfig({
},
build: {
target: ['chrome120', 'edge120', 'firefox120'],
// NOTE: Eventually we will add this back once we support multiple browsers
// outDir: `dist/${process.env.BROWSER_TARGET || 'chrome'}`,
emptyOutDir: true,
reportCompressedSize: false,
sourcemap: true,
Expand Down

0 comments on commit 1aa4e8c

Please sign in to comment.