ESPresense/ui/vite.config.js

123 lines
3.8 KiB
JavaScript

import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { resolve } from 'path';
import zlib from 'node:zlib';
import { promisify } from 'util';
import fs from 'fs/promises';
import { pascalCase } from "pascal-case";
import mime from 'mime';
import { createHtmlPlugin } from 'vite-plugin-html';
import strip from '@rollup/plugin-strip';
const gzip = promisify(zlib.gzip);
function hexdump(buffer) {
let lines = [];
for (let i = 0; i < buffer.length; i += 16) {
let block = buffer.slice(i, i + 16);
let hexArray = [];
for (let value of block) {
hexArray.push("0x" + value.toString(16).padStart(2, "0"));
}
let hexString = hexArray.join(", ");
let line = ` ${hexString}`;
lines.push(line);
}
return lines.join(",\n");
}
async function cppCompressed(input, fileName, contentType) {
const result = await gzip(input, { level: zlib.constants.Z_BEST_COMPRESSION });
console.info(fileName + " compressed " + result.length + " bytes");
const array = hexdump(result);
const src = `/*
* Binary array for the Web UI.
* Gzip is used for smaller size and improved speeds.
*/
// Autogenerated do not edit!!
const uint16_t ${fileName.replace(/[.-]/g, "_").toUpperCase()}_L = ${result.length};
const uint8_t ${fileName.replace(/[.-]/g, "_").toUpperCase()}[] PROGMEM = {
${array}
};
void serve${pascalCase(fileName.replace(/[.-]/g, "_"))}(AsyncWebServerRequest* request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "${contentType || mime.getType(fileName)}", ${fileName.replace(/[.-]/g, "_").toUpperCase()}, ${fileName.replace(/[.-]/g, "_").toUpperCase()}_L);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
`;
return src;
}
function cppPlugin() {
return {
name: 'cpp',
async writeBundle(options, bundle) {
for (const [fileName, file] of Object.entries(bundle)) {
if (file.type === 'chunk' || file.type === 'asset') {
const content = file.type === 'chunk' ? file.code : file.source;
const compressedContent = await cppCompressed(content, fileName);
// Adjust the output path to be two directories up
let outputPath = resolve(__dirname, '../src/ui_' + fileName.replace(/[.-]/g, '_') + '.h');
// Ensure the directory exists
await fs.mkdir(resolve(__dirname, '..'), { recursive: true });
// Write the file
await fs.writeFile(outputPath, compressedContent);
console.log(`Generated: ${outputPath}`);
}
}
}
};
}
export default defineConfig({
base: '/ui/',
plugins: [
svelte({
emitCss: true,
}),
strip({
include: '**/*.(js|ts|svelte)',
functions: ['console.*', 'assert.*'],
}),
createHtmlPlugin({
minify: true,
}),
cppPlugin()
],
build: {
outDir: 'dist',
assetsDir: '.',
minify: 'terser',
terserOptions: {
compress: {
ecma: 2020,
drop_console: true,
passes: 3,
toplevel: true,
unsafe: true,
},
mangle: {
toplevel: true,
},
output: {
comments: false,
},
},
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html')
},
output: {
entryFileNames: 'index.js',
assetFileNames: 'bundle.css',
},
},
cssCodeSplit: false, // This ensures a single CSS file
}
});