You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

207 lines
5.3 KiB

/**
* Vite Plugin for TimeSafari Daily Notification Plugin
*
* Provides Vite-specific optimizations and integrations for the TimeSafari PWA.
* Handles tree-shaking, SSR safety, and platform-specific builds.
*
* @author Matthew Raymer
* @version 1.0.0
*/
import type { Plugin } from 'vite';
export interface TimeSafariPluginOptions {
/**
* Enable SSR safety checks
*/
ssrSafe?: boolean;
/**
* Enable tree-shaking optimizations
*/
treeShaking?: boolean;
/**
* Platform-specific builds
*/
platforms?: ('android' | 'ios' | 'electron')[];
/**
* Bundle size budget in KB
*/
bundleSizeBudget?: number;
/**
* Enable development mode optimizations
*/
devMode?: boolean;
}
/**
* TimeSafari Vite Plugin
*
* Provides optimizations and integrations for TimeSafari PWA compatibility.
*/
export function timeSafariPlugin(options: TimeSafariPluginOptions = {}): Plugin {
const {
ssrSafe = true,
treeShaking = true,
platforms = ['android', 'ios'],
bundleSizeBudget = 35,
devMode = false
} = options;
return {
name: 'timesafari-daily-notification',
// Plugin configuration
// eslint-disable-next-line @typescript-eslint/no-explicit-any
config(config, { command }): any {
const isDev = command === 'serve';
return {
// Build optimizations
build: {
...config.build,
// Enable tree-shaking
rollupOptions: {
...config.build?.rollupOptions,
treeshake: treeShaking ? {
moduleSideEffects: false,
propertyReadSideEffects: false,
unknownGlobalSideEffects: false
} : false
}
},
// Define constants
define: {
...config.define,
__TIMESAFARI_SSR_SAFE__: ssrSafe,
__TIMESAFARI_PLATFORMS__: JSON.stringify(platforms),
__TIMESAFARI_BUNDLE_BUDGET__: bundleSizeBudget,
__TIMESAFARI_DEV_MODE__: devMode || isDev
}
};
},
// Transform code for SSR safety
// eslint-disable-next-line @typescript-eslint/no-explicit-any
transform(code, _id): any {
if (!ssrSafe) return null;
// Check for SSR-unsafe code patterns
const ssrUnsafePatterns = [
/window\./g,
/document\./g,
/navigator\./g,
/localStorage\./g,
/sessionStorage\./g,
];
let hasUnsafeCode = false;
for (const pattern of ssrUnsafePatterns) {
if (pattern.test(code)) {
hasUnsafeCode = true;
break;
}
}
if (hasUnsafeCode) {
// Wrap unsafe code in platform checks
const wrappedCode = `
// SSR-safe wrapper for TimeSafari Daily Notification Plugin
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
${code}
} else {
// SSR fallback - return mock implementation
// Running in SSR environment, using fallback implementation
}
`;
return {
code: wrappedCode,
map: null
};
}
return null;
},
// Generate platform-specific builds
generateBundle(_options, bundle): void {
// Remove any web-specific code (not applicable in native-first architecture)
Object.keys(bundle).forEach(fileName => {
if (fileName.includes('web') || fileName.includes('browser')) {
delete bundle[fileName];
}
});
if (!platforms.includes('android')) {
// Remove Android-specific code
Object.keys(bundle).forEach(fileName => {
if (fileName.includes('android')) {
delete bundle[fileName];
}
});
}
if (!platforms.includes('ios')) {
// Remove iOS-specific code
Object.keys(bundle).forEach(fileName => {
if (fileName.includes('ios')) {
delete bundle[fileName];
}
});
}
},
// Bundle size analysis
writeBundle(_options, bundle): void {
if (devMode) return;
let totalSize = 0;
const fileSizes: Record<string, number> = {};
Object.entries(bundle).forEach(([fileName, chunk]) => {
if (chunk.type === 'chunk') {
const size = Buffer.byteLength(chunk.code, 'utf8');
fileSizes[fileName] = size;
totalSize += size;
}
});
const totalSizeKB = totalSize / 1024;
if (totalSizeKB > bundleSizeBudget) {
// Bundle size exceeds budget
// Log largest files for debugging (available in fileSizes)
} else {
// Bundle size within budget
}
},
// Development server middleware
configureServer(server): void {
if (!devMode) return;
// Add development-specific middleware
server.middlewares.use('/timesafari-plugin', (_req, res, _next) => {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
name: 'TimeSafari Daily Notification Plugin',
version: process.env.npm_package_version || '1.0.0',
platforms: platforms,
ssrSafe: ssrSafe,
treeShaking: treeShaking
}));
});
}
};
}
/**
* Default export for easy usage
*/
export default timeSafariPlugin;