Skip to content

Instantly share code, notes, and snippets.

@0test
Last active November 29, 2025 15:20
Show Gist options
  • Select an option

  • Save 0test/4e4d4247abf6e664c2ba0cf41bb340b5 to your computer and use it in GitHub Desktop.

Select an option

Save 0test/4e4d4247abf6e664c2ba0cf41bb340b5 to your computer and use it in GitHub Desktop.
npm run build/dev
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Загрузка...</title>
<link rel="stylesheet" href="/template/app/public/water.css">
</head>
<body>
<div id="app"></div>
@vite_assets()
</body>
</html>
<?php
return [
'dev' => [
'host' => 'localhost',
'port' => 5173,
'entry' => 'src/main.js',
],
'prod' => [
'base_path' => '/template/dist/',
],
];
<?php namespace EvolutionCMS\Main;
use EvolutionCMS\Main\Services\Util;
use EvolutionCMS\ServiceProvider;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Blade;
class MainServiceProvider extends ServiceProvider
{
protected $namespace = 'main';
public function boot(){
Blade::directive('vite_assets', function ($params) {
return '<?php echo EvolutionCMS\Main\Services\Util::ViteAssets(' . $params . '); ?>';
});
}
public function register()
{
Route::group(['middleware' => 'bindings'], function () {
$this->loadRoutesFrom(__DIR__ . '/../routes.php');
});
}
}
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
base: '', // чтобы пути были относительные
build: {
outDir: '../dist', // кладём рядом с app/
emptyOutDir: true,
manifest: true,
rollupOptions: {
output: {
entryFileNames: `assets/index.js`, // имя основного JS-файла.
chunkFileNames: `assets/[name].js`, // имена асинхронных чанков (если они есть).
assetFileNames: `assets/[name].[ext]` // имена других ассетов (изображений, шрифтов и т.п.).
}
}
},
server: {
proxy: {
'/api': {
target: 'http://evoreact.localhost', // Evo сайт
changeOrigin: true,
},
},
},
})
<?php
namespace EvolutionCMS\Main\Services;
use RuntimeException;
class Util
{
public static function ViteAssets($params = []): string
{
$viteConfig = self::getViteConfig();
$isDev = self::isDevRunning(
$viteConfig['dev']['host'],
$viteConfig['dev']['port']
);
if ($isDev) {
$host = $viteConfig['dev']['host'] ;
$port = $viteConfig['dev']['port'];
$entry = $viteConfig['dev']['entry'];
return sprintf(
'<script type="module" src="http://%s:%d/%s"></script>',
htmlspecialchars($host, ENT_QUOTES, 'UTF-8'),
(int)$port,
htmlspecialchars($entry, ENT_QUOTES, 'UTF-8')
);
}
// Prod
$basePath = $viteConfig['prod']['base_path'] ;
$manifestPath = MODX_BASE_PATH . $basePath . '.vite/manifest.json';
if (!file_exists($manifestPath)) {
throw new RuntimeException('Vite manifest not found at ' . $manifestPath . '. Run `npm run build`.');
}
$manifest = json_decode(file_get_contents($manifestPath), true, 512, JSON_THROW_ON_ERROR);
$data = $manifest['index.html'] ?? null; // ну такой вот ключ
if (!$data) {
throw new RuntimeException("Entry not found in Vite manifest.");
}
$html = '';
foreach ($data['css'] ?? [] as $css) {
$url = rtrim($basePath, '/') . '/' . ltrim($css, '/');
$html .= '<link rel="stylesheet" href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '">' . "\n";
}
$jsUrl = rtrim($basePath, '/') . '/' . ltrim($data['file'], '/');
$html .= '<script type="module" src="' . htmlspecialchars($jsUrl, ENT_QUOTES, 'UTF-8') . '"></script>';
return $html;
}
private static function isDevRunning(string $host, int $port): bool
{
$sock = @fsockopen($host, $port, $errno, $errstr, 0.1);
if ($sock) {
fclose($sock);
return true;
}
return false;
}
private static function getViteConfig()
{
return evo()['config']['vite']['env'] ?? [
'dev' => [
'host' => 'localhost',
'port' => 5173,
'entry' => 'src/main.js',
],
'prod' => [
'base_path' => '/template/dist/',
],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment