Files
Berufsschule_HAM/src/critical.js

165 lines
4.5 KiB
JavaScript

import { generate } from 'critical';
import fs from 'fs';
import path from 'path';
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Login
await page.goto('http://localhost:5275/Home/Login');
await page.type('#username', 'admin');
await page.type('#password', 'Test1234.');
await page.click('button[type=submit]');
await page.waitForNavigation();
// Extract cookies
const cookies = await page.cookies();
await browser.close();
async function generateCriticalCSSForViews() {
const viewsDir = 'Views';
// Helper function to get all .cshtml files recursively
function getAllCshtmlFiles(dir) {
let results = [];
const list = fs.readdirSync(dir);
list.forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat && stat.isDirectory()) {
// Recursively get files from subdirectories
results = results.concat(getAllCshtmlFiles(filePath));
} else if (file.endsWith('.cshtml')) {
results.push(filePath);
}
});
return results;
}
// Helper function to convert file path to URL path
function filePathToUrlPath(filePath) {
// Remove 'Views/' prefix
let relativePath = filePath.replace(/^Views[\/\\]/, '');
// Remove .cshtml extension
relativePath = relativePath.replace(/\.cshtml$/, '');
// Convert to URL format (replace \ with / and capitalize first letter)
const urlPath = relativePath
.split(/[\/\\]/)
.map((segment, index) =>
index === 0 ? segment : segment.charAt(0).toUpperCase() + segment.slice(1)
)
.join('/');
// Handle the case where we have a single file (like Index.cshtml)
if (relativePath.includes('/')) {
// Convert to URL path format: Views/Home/Index.cshtml -> /Home/Index
return '/' + relativePath.replace(/\\/g, '/').replace(/\.cshtml$/, '');
} else {
// For files directly in Views folder (like Views/Index.cshtml)
return '/' + relativePath.replace(/\.cshtml$/, '');
}
}
// Get all .cshtml files
const cshtmlFiles = getAllCshtmlFiles(viewsDir);
// Create CriticalCSS directory if it doesn't exist
const criticalCssDir = 'CriticalCSS';
if (!fs.existsSync(criticalCssDir)) {
fs.mkdirSync(criticalCssDir, { recursive: true });
}
// Process each file
for (const file of cshtmlFiles) {
try {
const urlPath = filePathToUrlPath(file);
// Generate critical CSS
await generate({
src: `http://localhost:5275${urlPath}`,
inline: false,
width: 1920,
height: 1080,
penthouse: {
customHeaders: {
cookie: cookies.map(c => `${c.name}=${c.value}`).join('; ')
},
forceInclude: [
'[data-bs-theme=dark]',
'.navbar',
'.nav-link',
'.dropdown-menu',
'.me-2',
'.align-items-center',
'.d-flex',
'.position-fixed', // print batch
'.bottom-0',
'.start-0',
'.m-4',
'.row', // elements
'.row>*',
'.g-3',
'.col-md-3',
'.text-center',
'.mb-3',
'.mb-4',
'.mt-3',
'.py-4',
'.text-center',
'h2',
'.form-control',
'.form-control-sm',
'.modal',
'.btn',
'.btn-sm',
'.btn-secondary',
'.btn-warning',
'.btn-danger',
'.rounded-circle', // user icon
'table', // table elements (users)
'.table>thead',
'.user-row > td',
'thead',
'tbody',
'th',
'tr',
'td',
'.table>:not(caption)>*>*',
'.table-striped>tbody>tr:nth-of-type(odd)>*',
'.gap-2',
'.table',
'.table-responsive',
'.align-middle'
]
},
target: {
css: path.join(criticalCssDir, urlPath.replace(/\//g, '.').replace(/^\./, '') + '.css')
}
});
console.log(`Critical CSS generated for: ${urlPath}`);
} catch (err) {
console.error(`Error processing ${file}:`, err);
}
}
console.log('All critical CSS files generated!');
}
// Run the function
generateCriticalCSSForViews().catch(console.error);
// How to run this:
// install dependencies:
// npm i -D critical
// npm install puppeteer
// run:
// node critical.js