feat(build): add vite-build-logger (#507)
* feat(build): add vite-build-logger * chore: fix types * chore: fix logic --------- Co-authored-by: Preston-Cook <preston.l.cook@gmail.com>
This commit is contained in:
@@ -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';
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
@@ -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();
|
||||
@@ -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
|
||||
</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>
|
||||
|
||||
81
utils/plugins/vite-build-logger.ts
Normal file
81
utils/plugins/vite-build-logger.ts
Normal file
@@ -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`);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -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';
|
||||
@@ -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) {
|
||||
@@ -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: {
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user