Ctrl K
ComunidadGuías…

build.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * Copyright (c) Since 2024 InnoShop - All Rights Reserved
 *
 * @link       https://www.innoshop.com
 * @author     InnoShop <team@innoshop.com>
 * @license    https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 *
 * InnoShop Asset Build Script (Vite)
 *
 * Each entry is compiled independently via `npx vite build` with environment variables,
 * producing a single CSS or JS bundle per module. JS outputs are renamed from Vite's
 * default `index.js` to the desired filename.
 *
 * Usage:
 *   npm run build                        Build all core modules (front + panel + install)
 *   npm run prod                         Alias for build
 *   TARGET=front npm run build           Build only front module
 *   TARGET=panel npm run build           Build only panel module
 *   TARGET=install npm run build         Build only install module
 *   THEME=fdsodental npm run prod        Build only theme (skips core modules)
 *   TARGET=panel THEME=fdsodental npm run prod  Build panel + theme
 */

import { execSync } from 'child_process';
import fs from 'fs';

const theme = process.env.THEME || '';
const target = process.env.TARGET || '';
const startTime = Date.now();

const coreEntries = [
    { name: 'front/css', input: 'innopacks/front/resources/assets/scss/app.scss', outDir: 'public/build/front/css', outputName: 'app', group: 'front' },
    { name: 'front/js',  input: 'innopacks/front/resources/assets/js/app.js',   outDir: 'public/build/front/js',  outputName: 'app', group: 'front' },
    { name: 'panel/css', input: 'innopacks/panel/resources/assets/scss/app.scss', outDir: 'public/build/panel/css', outputName: 'app', group: 'panel' },
    { name: 'panel/js',  input: 'innopacks/panel/resources/assets/js/app.js',    outDir: 'public/build/panel/js',  outputName: 'app', group: 'panel' },
    { name: 'install/css', input: 'innopacks/install/resources/assets/scss/app.scss', outDir: 'public/build/install/css', outputName: 'app', group: 'install' },
];

// Filter by TARGET (front/panel/install), or skip core when building a theme
const entries = theme ? [] : coreEntries.filter(e => !target || e.group === target);

// Theme entries
if (theme) {
    const themeDir = `themes/${theme}`;
    const themeOut = `public/static/themes/${theme}`;

    ['css', 'js'].forEach(dir => {
        const p = `${themeOut}/${dir}`;
        if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });
    });

    if (fs.existsSync(`${themeDir}/assets/scss/app.scss`))
        entries.push({ name: 'theme/css', input: `${themeDir}/assets/scss/app.scss`, outDir: `${themeOut}/css`, outputName: 'app' });
    if (fs.existsSync(`${themeDir}/assets/js/app.js`))
        entries.push({ name: 'theme/js', input: `${themeDir}/assets/js/app.js`, outDir: `${themeOut}/js`, outputName: 'app' });
}

// Sync theme static assets (fonts, images, etc.) to public/static
if (theme) {
    const targetDir = `public/static/themes/${theme}`;
    const distDir = `themes/${theme}/public`;
    const skipDirs = new Set(['css', 'js']);
    if (fs.existsSync(distDir)) {
        fs.readdirSync(distDir).forEach(item => {
            if (skipDirs.has(item)) return;
            const src = `${distDir}/${item}`;
            const dest = `${targetDir}/${item}`;
            fs.cpSync(src, dest, { recursive: true, force: true });
        });
        console.log('  ✓ static assets synced');
    }
}

if (entries.length === 0) {
    console.log('No entries to build.');
    process.exit(0);
}

let failed = 0;
for (const entry of entries) {
    try {
        execSync(
            `npx vite build`,
            { stdio: 'pipe', env: { ...process.env, BUILD_INPUT: entry.input, BUILD_OUTDIR: entry.outDir, BUILD_OUTPUT_NAME: entry.outputName } }
        );
        // Vite lib IIFE always outputs as index.js — rename to desired name
        if (entry.input.endsWith('.js')) {
            const idx = `${entry.outDir}/index.js`;
            const target = `${entry.outDir}/${entry.outputName}.js`;
            if (fs.existsSync(idx) && idx !== target) {
                fs.renameSync(idx, target);
            }
        }
        console.log(`  ✓ ${entry.name}`);
    } catch (e) {
        console.error(`  ✗ ${entry.name}`);
        const err = e.stderr?.toString() || '';
        err.split('\n').filter(l => l.includes('Error')).slice(0, 3).forEach(l => console.error(`    ${l}`));
        failed++;
    }
}

// Theme distribution: copy built CSS/JS back to theme public dir (for git commit)
if (theme) {
    const targetDir = `public/static/themes/${theme}`;
    const distDir = `themes/${theme}/public`;
    ['css', 'js'].forEach(dir => {
        const src = `${targetDir}/${dir}`;
        const dest = `${distDir}/${dir}`;
        if (fs.existsSync(src)) {
            fs.mkdirSync(dest, { recursive: true });
            fs.readdirSync(src).forEach(file => fs.copyFileSync(`${src}/${file}`, `${dest}/${file}`));
        }
    });
}

// Linux permissions
if (process.platform === 'linux' && fs.existsSync('public')) {
    try { execSync('chmod -R 755 public', { stdio: 'pipe' }); } catch {}
    try { execSync('chown -R www:www public', { stdio: 'pipe' }); } catch {}
}

const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\nDone in ${elapsed}s${failed ? ` (${failed} failed)` : ''}`);