rentgen/esbuild.config.js
am0 6806537531 refactor: poprawki code review w build_time_abstraction
## Zmiany

### sidebar.tsx
- Przywrócono niełamiące spacje (U+00A0) przed krótkimi przyimkami (https://unicode-explorer.com/c/00A0)

### esbuild_config.js - zasada DRY
- Zastąpiono powielone bloki kopiowania 'components/' i 'assets/'
  pojedynczą pętlą 'for' po tablicy ['components', 'assets']
- Zastąpiono powielone bloki kopiowania zależności z 'node_modules'
  ('react/umd', 'react-dom/umd', 'survey-react') pętlą iterującą
  po tablicy obiektów 'nodeDeps'; zależności z selektywnym kopiowaniem
  plików obsługiwane są przez opcjonalne pole 'files'

## Bez zmian funkcjonalnych
Wszystkie powyższe zmiany są wyłącznie refaktoryzacją - zachowanie buildu dla obu targetów (Firefox i Chrome) pozostaje identyczne.
2026-02-18 13:18:44 +01:00

164 lines
6.2 KiB
JavaScript

import esbuild from 'esbuild';
import scss from 'esbuild-plugin-sass';
import { copyFileSync, mkdirSync, readdirSync, existsSync } from 'fs';
import { join, dirname } from 'path';
// Określenie platformy docelowej: firefox (domyślnie) lub chrome
const TARGET = process.env.TARGET || 'firefox';
const IS_FIREFOX = TARGET === 'firefox';
const IS_CHROME = TARGET === 'chrome';
// Katalogi wyjściowe
const DIST_DIR = IS_FIREFOX ? './dist-firefox' : './dist-chrome';
const LIB_DIR = join(DIST_DIR, 'lib');
console.log(`🎯 Budowanie dla: ${TARGET.toUpperCase()}`);
console.log(`📁 Katalog wyjściowy: ${DIST_DIR}`);
const watch = process.argv.includes('--watch') && {
onRebuild(error) {
if (error) console.error('[watch] budowanie nie powiodło się', error);
else console.log('[watch] budowanie zakończone');
},
};
// Funkcja pomocnicza: rekurencyjne kopiowanie katalogów
function copyDir(src, dest) {
if (!existsSync(dest)) {
mkdirSync(dest, { recursive: true });
}
const entries = readdirSync(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = join(src, entry.name);
const destPath = join(dest, entry.name);
if (entry.isDirectory()) {
copyDir(srcPath, destPath);
} else {
copyFileSync(srcPath, destPath);
}
}
}
// Plugin: kopiowanie plików statycznych po zakończeniu budowania
const copyStaticFiles = {
name: 'copy-static-files',
setup(build) {
build.onEnd(() => {
console.log('📋 Kopiowanie plików statycznych...');
// Kopiowanie manifestu (wybór na podstawie platformy docelowej)
const manifestSrc = IS_FIREFOX ? './manifest.json' : './manifest-chrome.json';
const manifestDest = join(DIST_DIR, 'manifest.json');
mkdirSync(dirname(manifestDest), { recursive: true });
copyFileSync(manifestSrc, manifestDest);
console.log(` ✓ Skopiowano ${manifestSrc}${manifestDest}`);
// Kopiowanie katalogów statycznych
for (const dir of ['components', 'assets']) {
if (existsSync(`./${dir}`)) {
copyDir(`./${dir}`, join(DIST_DIR, dir));
console.log(` ✓ Skopiowano ${dir}/`);
}
}
// Kopiowanie wymaganych bibliotek z node_modules (potrzebne dla plików HTML z UMD React)
const nodeModulesDest = join(DIST_DIR, 'node_modules');
const nodeDeps = [
{ src: 'react/umd', dest: 'react/umd' },
{ src: 'react-dom/umd', dest: 'react-dom/umd' },
{ src: 'survey-react', dest: 'survey-react', files: ['survey.react.min.js', 'survey.react.min.css'] },
];
for (const dep of nodeDeps) {
const srcPath = `./node_modules/${dep.src}`;
const destPath = join(nodeModulesDest, dep.dest);
if (existsSync(srcPath)) {
if (dep.files) {
mkdirSync(destPath, { recursive: true });
dep.files.forEach(file => {
const fileSrc = join(srcPath, file);
if (existsSync(fileSrc)) copyFileSync(fileSrc, join(destPath, file));
});
} else {
copyDir(srcPath, destPath);
}
console.log(` ✓ Skopiowano node_modules/${dep.src}/`);
}
}
console.log(`✅ Budowanie dla ${TARGET.toUpperCase()} zakończone!`);
});
},
};
// Zobacz: https://github.com/evanw/esbuild/issues/806#issuecomment-779138268
// Plugin pomijający importy React (używamy globalnych obiektów z UMD)
let skipReactImports = {
name: 'skipReactImports',
setup(build) {
build.onResolve({ filter: /^(react(-dom)?|survey-react)$/ }, (args) => {
return {
path: args.path,
namespace: `globalExternal_${args.path}`,
};
});
build.onLoad({ filter: /.*/, namespace: 'globalExternal_react' }, () => {
return {
contents: `module.exports = globalThis.React`,
loader: 'js',
};
});
build.onLoad({ filter: /.*/, namespace: 'globalExternal_react-dom' }, () => {
return {
contents: `module.exports = globalThis.ReactDOM`,
loader: 'js',
};
});
build.onLoad({ filter: /.*/, namespace: 'globalExternal_survey-react' }, () => {
return {
contents: `module.exports = globalThis.Survey`,
loader: 'js',
};
});
},
};
esbuild
.build({
entryPoints: [
// JavaScript/TypeScript
'components/toolbar/toolbar.tsx',
'components/sidebar/sidebar.tsx',
'components/report-window/report-window.tsx',
'background.ts',
'diag.tsx',
// Globalne style
'styles/global.scss',
'styles/fonts.scss',
// Style komponentów (kompilowane osobno)
'components/toolbar/toolbar.scss',
// 'components/sidebar/sidebar.scss',
// 'components/report-window/report-window.scss',
],
bundle: true,
// minify: true,
outdir: LIB_DIR,
loader: { '.woff': 'file', '.woff2': 'file' },
plugins: [scss(), skipReactImports, copyStaticFiles],
define: {
PLUGIN_NAME: '"Rentgen"',
PLUGIN_URL: '"https://addons.mozilla.org/pl/firefox/addon/rentgen/"',
'process.env.TARGET': JSON.stringify(TARGET),
},
external: ['react', 'react-dom', 'survey-react'],
watch,
})
.then(() => console.log(`\n🎉 Dodatek dla ${TARGET.toUpperCase()} zbudowany pomyślnie!\n`))
.catch(() => process.exit(1));