123 lines
3.8 KiB
JavaScript
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
|
|
}
|
|
});
|