Files
streamyfin/metro.config.js
Uruk edc9c8640d perf: optimize EAS build caching and Metro bundling
Improves build performance by adding platform-specific cache paths including Gradle and iOS Pods directories. Updates cache keys to use app.config.js instead of package.json for more accurate invalidation.

Enhances Metro minification with Hermes-optimized settings, adds ASCII-only output, and enables advanced compression optimizations like dead code elimination and variable reduction.

Configures production environment variables for bundle size optimization across preview and production builds.
2025-09-26 16:31:01 +02:00

244 lines
6.4 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const path = require("node:path");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
// =======================================================
// STREAMYFIN METRO CONFIG - PERFORMANCE OPTIMIZED 🚀
// =======================================================
// Advanced configuration for multi-platform Jellyfin client
// Optimized for media streaming, TV support, and Bun
// =======================================================
// HERMES + ADVANCED PERFORMANCE
// ==============================
config.transformer.hermesParser = true;
// CPU optimization (your existing setting)
const os = require("node:os");
config.maxWorkers = Math.max(1, os.cpus().length - 1);
// JAVASCRIPT OPTIMIZATION (Safe & Stable)
// ========================================
config.transformer = {
...config.transformer,
hermesParser: true,
// NEW: Inline requires for 15-30% startup improvement
inlineRequires: true,
// ADVANCED: Hermes-optimized minification for streaming apps
minifierConfig: {
mangle: {
keep_fnames: process.env.NODE_ENV === "development",
},
output: {
ascii_only: true,
beautify: false,
semicolons: false,
},
compress: {
// Production-only optimizations
drop_console: process.env.NODE_ENV === "production",
dead_code: true,
drop_debugger: true,
conditionals: true,
evaluate: true,
unused: true,
reduce_vars: true,
// Keep class names for error reporting
keep_classnames: true,
// Preserve function names for performance profiling in dev
keep_fnames: process.env.NODE_ENV === "development",
},
},
};
// RESOLVER OPTIMIZATIONS ENHANCED
// ===============================
config.resolver = {
...config.resolver,
// NEW: Package exports (stable in recent Metro)
unstable_enablePackageExports: true,
// ENHANCED: Extensions optimized for Streamyfin
assetExts: [
...config.resolver.assetExts,
// Video formats (enhanced for Jellyfin)
"mkv",
"mp4",
"avi",
"mov",
"wmv",
"flv",
"webm",
"m4v",
"mpg",
"mpeg",
// Audio formats
"mp3",
"wav",
"flac",
"aac",
"m4a",
"ogg",
"wma",
"opus",
// Subtitle files (complete for media)
"srt",
"vtt",
"ass",
"ssa",
"sub",
"idx",
"sbv",
"ttml",
// Database/Cache
"db",
"sqlite",
"realm",
"json5",
// Fonts (TV optimized)
"woff2",
"woff",
"eot",
"otf",
// Images (enhanced for thumbnails)
"avif",
"heic",
"heif", // Modern formats
],
sourceExts: [
...config.resolver.sourceExts,
"mjs",
"cjs", // Modern JS support
],
// NEW: Platform prioritization for performance
platforms: ["ios", "android", "native", "web", "tv"],
};
// SERIALIZER OPTIMIZATIONS (Production)
// ====================================
if (process.env.NODE_ENV === "production") {
config.serializer = {
...config.serializer,
// NEW: Module IDs optimized for caching
createModuleIdFactory: () => {
return (path) => {
// Shorter module IDs for smaller bundles
return require("node:crypto")
.createHash("sha1")
.update(path)
.digest("hex")
.substring(0, 8);
};
},
// NEW: Bundle pre-loading for streaming apps
getModulesRunBeforeMainModule: (_entryFilePath) => [
// Pre-load critical modules for faster TTI
require.resolve("react-native/Libraries/Core/InitializeCore"),
],
// Web bundle splitting (if applicable)
...(process.env.EXPO_PLATFORM === "web" && {
// Experimental code splitting for web
experimentalSerializerHook: () => {},
}),
};
}
// TV PLATFORM ENHANCEMENTS
// ========================
if (process.env?.EXPO_TV === "1") {
const originalSourceExts = config.resolver.sourceExts;
const tvSourceExts = [
...originalSourceExts.map((ext) => `tv.${ext}`),
...originalSourceExts,
];
config.resolver.sourceExts = tvSourceExts;
// NEW: TV-specific optimizations
config.transformer = {
...config.transformer,
// Optimize transforms for TV hardware
experimentalImportSupport: false, // Reduce complexity on TV
// Use legacy transformer for better TV compatibility
allowOptionalDependencies: true,
};
console.log("📺 TV platform optimized for Streamyfin");
console.log(`📁 TV extensions: ${tvSourceExts.slice(0, 6).join(", ")}...`);
}
// DEVELOPMENT ENHANCEMENTS
// ========================
if (process.env.NODE_ENV === "development") {
// NEW: Enhanced error reporting
config.reporter = {
update: (event) => {
if (event.type === "bundle_build_failed") {
console.error(
"🔴 Streamyfin Bundle Build Failed:",
event.error.message,
);
} else if (event.type === "bundle_build_done") {
console.log(
"✅ Streamyfin Bundle Ready:",
event.bundleDetails?.bundleSize || "Unknown size",
);
}
},
};
console.log("🚀 Streamyfin Metro Config - OPTIMIZED VERSION");
console.log(`📦 Workers: ${config.maxWorkers}`);
console.log(`🎯 Hermes: ${config.transformer.hermesParser}`);
console.log(`⚡ Inline requires: ${config.transformer.inlineRequires}`);
console.log(
`📺 TV support: ${process.env.EXPO_TV === "1" ? "ENABLED" : "DISABLED"}`,
);
}
// STREAMING APP SPECIFIC OPTIMIZATIONS
// ===================================
// NEW: Cache hints for better performance
if (typeof config.cacheStores === "undefined") {
// Only add if not causing issues
try {
const MetroCache = require("metro-cache");
config.cacheStores = [
new MetroCache.FileStore({
root: path.join(os.tmpdir(), "streamyfin-metro-cache"),
}),
];
} catch (_e) {
// Fallback: use default cache
console.log(" Using default Metro cache (custom cache not available)");
}
}
// NEW: Network request optimizations for streaming
config.server = {
...config.server,
// Enhanced request handling for media assets
enhanceMiddleware: (middleware, _server) => {
// Add caching headers for static assets
return (req, res, next) => {
if (req.url?.match(/\.(mp4|mkv|jpg|jpeg|png|webp)$/)) {
res.setHeader("Cache-Control", "public, max-age=31536000");
}
return middleware(req, res, next);
};
},
};
module.exports = config;