build and create deploy production
This commit is contained in:
180
BUILD_GUIDE.md
Normal file
180
BUILD_GUIDE.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# 🚀 Panduan Build untuk Production
|
||||
|
||||
## 📋 Masalah yang Diselesaikan
|
||||
|
||||
Aplikasi ini memiliki **banyak file JS dan CSS** yang harus dibangun semuanya karena:
|
||||
- Setiap halaman memerlukan file JS/CSS yang spesifik
|
||||
- Jika ada file yang hilang, halaman akan error (404 Not Found)
|
||||
- Server dengan RAM terbatas sering mengalami "killed" saat build
|
||||
|
||||
## 🎯 Solusi yang Tersedia
|
||||
|
||||
### 1. **Build di Local (RECOMMENDED) 🏆**
|
||||
```bash
|
||||
# Build di local computer Anda
|
||||
npm run build:local
|
||||
|
||||
# Upload ke server
|
||||
./deploy.sh username server.com /path/to/project
|
||||
```
|
||||
|
||||
**Kelebihan:**
|
||||
- ✅ Tidak ada batasan memory
|
||||
- ✅ Build lebih cepat
|
||||
- ✅ Semua file terjamin ter-build
|
||||
|
||||
### 2. **Build di Server dengan Optimasi**
|
||||
```bash
|
||||
# Option A: Build dengan memory optimization
|
||||
npm run build:prod
|
||||
|
||||
# Option B: Build dengan retry mechanism
|
||||
npm run build:chunked
|
||||
|
||||
# Option C: Build manual dengan script
|
||||
./build-production.sh
|
||||
```
|
||||
|
||||
### 3. **Setup Server untuk Build**
|
||||
```bash
|
||||
# Setup swap memory dan optimasi (run dengan sudo)
|
||||
sudo ./server-setup.sh
|
||||
|
||||
# Kemudian build
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
## 📁 File yang Akan Dibangun
|
||||
|
||||
Semua file ini **WAJIB** ada karena dibutuhkan oleh halaman-halaman aplikasi:
|
||||
|
||||
### CSS Files:
|
||||
- `resources/scss/style.scss` - Main stylesheet
|
||||
- `resources/scss/icons.scss` - Icons
|
||||
- `resources/scss/components/_*.scss` - Components
|
||||
- `resources/scss/dashboards/_*.scss` - Dashboard styles
|
||||
- `resources/scss/pages/quick-search/*.scss` - Quick search pages
|
||||
- Third-party CSS (Quill, Flatpickr, GridJS, dll)
|
||||
|
||||
### JS Files:
|
||||
- **Core:** `app.js`, `config.js`, `dashboard.js`
|
||||
- **Pages:** `chart.js`, `form-*.js`, `table-*.js`, `maps-*.js`
|
||||
- **Data:** `data-advertisements.js`, `data-umkm.js`, `data-tourisms.js`
|
||||
- **Settings:** `syncronize.js`, `general-settings.js`
|
||||
- **Dashboards:** `bigdata.js`, `pbg.js`, `potentials/*.js`
|
||||
- **Users & Roles:** `users/*.js`, `roles/*.js`, `menus/*.js`
|
||||
- **Reports:** `growth-report.js`, `tourisms/index.js`
|
||||
- **Dan semua file lainnya sesuai kebutuhan halaman**
|
||||
|
||||
## ⚙️ Konfigurasi Build
|
||||
|
||||
### Memory Optimization
|
||||
```javascript
|
||||
// vite.config.production.js
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
vendor: ['bootstrap', 'moment', 'axios'],
|
||||
charts: ['apexcharts'],
|
||||
maps: ['leaflet', 'jsvectormap', 'gmaps'],
|
||||
ui: ['sweetalert2', 'flatpickr', 'quill']
|
||||
}
|
||||
},
|
||||
maxParallelFileOps: 1 // Untuk server dengan RAM terbatas
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Memory Limits
|
||||
```bash
|
||||
# Untuk server dengan RAM 2GB+
|
||||
NODE_OPTIONS="--max-old-space-size=2048"
|
||||
|
||||
# Untuk server dengan RAM 1GB
|
||||
NODE_OPTIONS="--max-old-space-size=1024"
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Build Terkill (Killed)
|
||||
```bash
|
||||
# Solusi 1: Build di local
|
||||
npm run build:local
|
||||
./deploy.sh
|
||||
|
||||
# Solusi 2: Tambah swap memory
|
||||
sudo ./server-setup.sh
|
||||
|
||||
# Solusi 3: Gunakan build chunked
|
||||
npm run build:chunked
|
||||
```
|
||||
|
||||
### File JS/CSS Tidak Ditemukan
|
||||
```bash
|
||||
# Pastikan semua file ada di vite.config.production.js
|
||||
# Jangan hapus file apapun dari daftar input!
|
||||
|
||||
# Verifikasi build
|
||||
find public/build -name "*.js" | wc -l
|
||||
find public/build -name "*.css" | wc -l
|
||||
```
|
||||
|
||||
### Server Kehabisan Memory
|
||||
```bash
|
||||
# Check memory usage
|
||||
free -h
|
||||
|
||||
# Add swap file
|
||||
sudo fallocate -l 2G /swapfile
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
```
|
||||
|
||||
## 📦 Deployment Flow
|
||||
|
||||
### Local Build → Server Deploy
|
||||
```bash
|
||||
# 1. Di local
|
||||
npm ci
|
||||
npm run build:local
|
||||
|
||||
# 2. Edit deploy.sh dengan info server
|
||||
# 3. Deploy
|
||||
./deploy.sh username server.com /path/to/project
|
||||
```
|
||||
|
||||
### Server Build
|
||||
```bash
|
||||
# 1. Setup server
|
||||
sudo ./server-setup.sh
|
||||
|
||||
# 2. Install dependencies
|
||||
npm ci --production=false
|
||||
|
||||
# 3. Build
|
||||
npm run build:chunked
|
||||
|
||||
# 4. Optimize Laravel
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
```
|
||||
|
||||
## ⚠️ Catatan Penting
|
||||
|
||||
1. **JANGAN HAPUS FILE APAPUN** dari `vite.config.production.js`
|
||||
2. **SEMUA FILE WAJIB ADA** karena dibutuhkan oleh halaman-halaman aplikasi
|
||||
3. **BUILD DI LOCAL** adalah solusi terbaik untuk server dengan RAM terbatas
|
||||
4. **BACKUP** selalu sebelum deploy ke production
|
||||
|
||||
## 🎉 Success Indicators
|
||||
|
||||
Build berhasil jika:
|
||||
- ✅ File `public/build/manifest.json` ada
|
||||
- ✅ Folder `public/build/assets/` berisi banyak file JS/CSS
|
||||
- ✅ Tidak ada error 404 saat mengakses halaman
|
||||
- ✅ Semua halaman dapat memuat JS/CSS yang dibutuhkan
|
||||
92
build-chunked.sh
Executable file
92
build-chunked.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Build script bertahap untuk menghindari memory overload
|
||||
# Tetap membangun SEMUA file yang diperlukan tapi secara bertahap
|
||||
|
||||
echo "🔨 Starting chunked production build..."
|
||||
|
||||
# Set memory limit
|
||||
export NODE_OPTIONS="--max-old-space-size=1536"
|
||||
export NODE_ENV=production
|
||||
|
||||
# Clean previous build
|
||||
echo "🧹 Cleaning previous build..."
|
||||
rm -rf public/build/*
|
||||
|
||||
# Fungsi untuk build dengan retry
|
||||
build_with_retry() {
|
||||
local config_file=$1
|
||||
local attempt=1
|
||||
local max_attempts=3
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
echo "🔄 Build attempt $attempt of $max_attempts..."
|
||||
|
||||
if vite build --config $config_file; then
|
||||
echo "✅ Build successful on attempt $attempt"
|
||||
return 0
|
||||
else
|
||||
echo "❌ Build failed on attempt $attempt"
|
||||
if [ $attempt -lt $max_attempts ]; then
|
||||
echo "⏳ Waiting 5 seconds before retry..."
|
||||
sleep 5
|
||||
# Clear memory caches
|
||||
sync && echo 3 > /proc/sys/vm/drop_caches 2>/dev/null || true
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
echo "📦 Building all assets with memory optimization..."
|
||||
|
||||
# Try building with production config first
|
||||
if build_with_retry "vite.config.production.js"; then
|
||||
echo "🎉 Build completed successfully!"
|
||||
echo "📊 Build summary:"
|
||||
du -sh public/build/* 2>/dev/null || echo "Build files created"
|
||||
|
||||
# Count generated files
|
||||
echo "📁 Generated files:"
|
||||
find public/build -type f | wc -l | xargs echo "Total files:"
|
||||
|
||||
else
|
||||
echo "❌ Build failed after all attempts!"
|
||||
echo ""
|
||||
echo "💡 Alternative solutions:"
|
||||
echo " 1. ✨ Build locally: npm run build:local"
|
||||
echo " 2. 🔧 Increase server memory/swap"
|
||||
echo " 3. ☁️ Use GitHub Actions CI/CD"
|
||||
echo " 4. 🚀 Use deployment services (Vercel, Netlify)"
|
||||
echo ""
|
||||
echo "🏠 For local build and deploy:"
|
||||
echo " npm run build:local"
|
||||
echo " ./deploy.sh your-username your-server.com /path/to/project"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔍 Verifying all essential files are built..."
|
||||
|
||||
# Check for essential files
|
||||
essential_files=(
|
||||
"public/build/manifest.json"
|
||||
"public/build/assets"
|
||||
)
|
||||
|
||||
missing_files=()
|
||||
for file in "${essential_files[@]}"; do
|
||||
if [ ! -e "$file" ]; then
|
||||
missing_files+=("$file")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_files[@]} -eq 0 ]; then
|
||||
echo "✅ All essential files are present!"
|
||||
else
|
||||
echo "⚠️ Missing files:"
|
||||
printf ' %s\n' "${missing_files[@]}"
|
||||
fi
|
||||
43
build-production.sh
Executable file
43
build-production.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Production build script dengan optimasi memory
|
||||
# Untuk server dengan resource terbatas
|
||||
|
||||
echo "🔨 Starting production build with memory optimization..."
|
||||
|
||||
# Set Node.js memory limit (adjust sesuai RAM server)
|
||||
# Untuk server dengan banyak file, gunakan memory yang lebih besar
|
||||
export NODE_OPTIONS="--max-old-space-size=2048 --max-semi-space-size=1024"
|
||||
|
||||
# Use production vite config
|
||||
export NODE_ENV=production
|
||||
|
||||
# Clean previous build
|
||||
echo "🧹 Cleaning previous build..."
|
||||
rm -rf public/build/*
|
||||
|
||||
# Build with limited resources
|
||||
echo "📦 Building assets with memory optimization..."
|
||||
|
||||
# Option 1: Build with custom config
|
||||
vite build --config vite.config.production.js
|
||||
|
||||
# Option 2: Alternative - build in chunks (uncomment if needed)
|
||||
# echo "Building CSS files first..."
|
||||
# vite build --config vite.config.production.js --mode css-only
|
||||
#
|
||||
# echo "Building JS files..."
|
||||
# vite build --config vite.config.production.js --mode js-only
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Build completed successfully!"
|
||||
echo "📊 Build summary:"
|
||||
du -sh public/build/*
|
||||
else
|
||||
echo "❌ Build failed!"
|
||||
echo "💡 Try these solutions:"
|
||||
echo " 1. Increase server memory"
|
||||
echo " 2. Build locally and upload files"
|
||||
echo " 3. Use swap memory (temporary solution)"
|
||||
exit 1
|
||||
fi
|
||||
73
deploy.sh
73
deploy.sh
@@ -1,39 +1,52 @@
|
||||
GIT_BRANCH="dev"
|
||||
PHP_VERSION="php8.3"
|
||||
#!/bin/bash
|
||||
|
||||
echo "🚀 Starting deployment..."
|
||||
php artisan down
|
||||
# Deploy script untuk build di local dan upload ke server
|
||||
# Usage: ./deploy.sh [server-user] [server-host] [server-path]
|
||||
|
||||
echo "📥 Pulling latest changes from Git..."
|
||||
git fetch origin $GIT_BRANCH
|
||||
git reset --hard origin/$GIT_BRANCH
|
||||
git pull origin $GIT_BRANCH
|
||||
# Default values (ganti sesuai server Anda)
|
||||
SERVER_USER=${1:-"your-username"}
|
||||
SERVER_HOST=${2:-"your-server.com"}
|
||||
SERVER_PATH=${3:-"/path/to/your/project"}
|
||||
|
||||
echo "⚡ Installing NPM dependencies and building assets..."
|
||||
npm ci --no-audit --no-fund
|
||||
echo "🚀 Starting deployment process..."
|
||||
|
||||
# 1. Clean previous build
|
||||
echo "🧹 Cleaning previous build..."
|
||||
rm -rf public/build/*
|
||||
|
||||
# 2. Install dependencies (jika belum)
|
||||
echo "📦 Installing dependencies..."
|
||||
npm ci --production=false
|
||||
|
||||
# 3. Build project
|
||||
echo "🔨 Building project..."
|
||||
npm run build
|
||||
|
||||
echo "📦 Installing composer dependencies..."
|
||||
COMPOSER_ALLOW_SUPERUSER=1 composer install --no-interaction --optimize-autoloader
|
||||
# Check if build was successful
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🗄️ Running migrations..."
|
||||
php artisan migrate --force
|
||||
echo "✅ Build completed successfully!"
|
||||
|
||||
echo "Running seeders..."
|
||||
php artisan db:seed --force
|
||||
# 4. Upload build files to server
|
||||
echo "📤 Uploading build files to server..."
|
||||
rsync -avz --progress --delete public/build/ $SERVER_USER@$SERVER_HOST:$SERVER_PATH/public/build/
|
||||
|
||||
echo "⚡ Optimizing application..."
|
||||
php artisan optimize:clear
|
||||
# 5. Upload other necessary files (optional)
|
||||
echo "📤 Uploading other files..."
|
||||
rsync -avz --progress \
|
||||
--exclude='node_modules' \
|
||||
--exclude='.git' \
|
||||
--exclude='public/build' \
|
||||
--exclude='storage/logs/*' \
|
||||
--exclude='bootstrap/cache/*' \
|
||||
./ $SERVER_USER@$SERVER_HOST:$SERVER_PATH/
|
||||
|
||||
echo "🔄 Restarting PHP service..."
|
||||
systemctl reload $PHP_VERSION-fpm
|
||||
|
||||
echo "🔁 Restarting Supervisor queue workers..."
|
||||
php artisan queue:restart
|
||||
|
||||
supervisorctl reread
|
||||
supervisorctl update
|
||||
supervisorctl restart all
|
||||
|
||||
php artisan up
|
||||
echo "🚀 Deployment completed successfully!"
|
||||
echo "🎉 Deployment completed successfully!"
|
||||
echo "Don't forget to run the following commands on the server:"
|
||||
echo " - composer install --no-dev --optimize-autoloader"
|
||||
echo " - php artisan config:cache"
|
||||
echo " - php artisan route:cache"
|
||||
echo " - php artisan view:cache"
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "www",
|
||||
"name": "sibedas-pbg-web",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"build:prod": "NODE_OPTIONS='--max-old-space-size=2048 --max-semi-space-size=1024' vite build --config vite.config.production.js",
|
||||
"build:chunked": "./build-chunked.sh",
|
||||
"build:local": "vite build && echo 'Build completed! Now run: ./deploy.sh to upload to server'",
|
||||
"dev": "vite"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
var u=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function f(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function l(e){if(e.__esModule)return e;var r=e.default;if(typeof r=="function"){var t=function o(){return this instanceof o?Reflect.construct(r,arguments,this.constructor):r.apply(this,arguments)};t.prototype=r.prototype}else t={};return Object.defineProperty(t,"__esModule",{value:!0}),Object.keys(e).forEach(function(o){var n=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,n.get?n:{enumerable:!0,get:function(){return e[o]}})}),t}export{f as a,u as c,l as g};
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 1.2 MiB |
@@ -1 +0,0 @@
|
||||
(function(){var i=sessionStorage.getItem("__DARKONE_CONFIG__"),e=document.getElementsByTagName("html")[0],a={theme:"light",topbar:{color:"light"},menu:{size:"default",color:"light"}};document.getElementsByTagName("html")[0];var t=Object.assign(JSON.parse(JSON.stringify(a)),{});(t=Object.assign(JSON.parse(JSON.stringify(a)),{})).theme=e.getAttribute("data-bs-theme")||a.theme,t.topbar.color=e.getAttribute("data-topbar-color")||a.topbar.color,t.menu.color=e.getAttribute("data-sidebar-color")||a.menu.color,t.menu.size=e.getAttribute("data-sidebar-size")||a.menu.size,window.defaultConfig=JSON.parse(JSON.stringify(t)),i!==null&&(t=JSON.parse(i)),(window.config=t)&&(e.setAttribute("data-bs-theme",t.theme),e.setAttribute("data-topbar-color",t.topbar.color),e.setAttribute("data-sidebar-color",t.menu.color),window.innerWidth<=1140?e.setAttribute("data-sidebar-size","hidden"):e.setAttribute("data-sidebar-size",t.menu.size))})();
|
||||
@@ -1 +0,0 @@
|
||||
import{A as t}from"./apexcharts.common-7mov3gaG.js";import{j as i}from"./world-BH8KG5u4.js";import"./_commonjsHelpers-C4iS2aBk.js";var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[25,28,32,38,43,55,60,48,42,51,35]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart01"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[87,54,4,76,31,95,70,92,53,9,6]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart02"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[41,42,35,42,6,12,13,22,42,94,95]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart03"),r).render();var r={chart:{type:"area",height:50,sparkline:{enabled:!0}},series:[{data:[8,41,40,48,77,35,0,77,63,100,71]}],stroke:{width:2,curve:"smooth"},markers:{size:0},colors:["#7e67fe"],tooltip:{fixed:{enabled:!1},x:{show:!1},y:{title:{formatter:function(e){return""}}},marker:{show:!1}},fill:{opacity:[1],type:["gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,100]}}};new t(document.querySelector("#chart04"),r).render();var a={chart:{height:180,type:"donut"},series:[44.25,52.68,45.98],legend:{show:!1},stroke:{width:0},plotOptions:{pie:{donut:{size:"70%",labels:{show:!1,total:{showAlways:!0,show:!0}}}}},labels:["Direct","Affilliate","Sponsored"],colors:["#7e67fe","#17c553","#7942ed"],dataLabels:{enabled:!1},responsive:[{breakpoint:480,options:{chart:{width:200}}}],fill:{type:"gradient"}},o=new t(document.querySelector("#conversions"),a);o.render();var a={series:[{name:"Page Views",type:"bar",data:[34,65,46,68,49,61,42,44,78,52,63,67]},{name:"Clicks",type:"area",data:[8,12,7,17,21,11,5,9,7,29,12,35]},{name:"Revenue",type:"area",data:[12,16,11,22,28,25,15,29,35,45,42,48]}],chart:{height:330,type:"line",toolbar:{show:!1}},stroke:{dashArray:[0,0,2],width:[0,2,2],curve:"smooth"},fill:{opacity:[1,1,1],type:["solid","gradient","gradient"],gradient:{type:"vertical",inverseColors:!1,opacityFrom:.5,opacityTo:0,stops:[0,90]}},markers:{size:[0,0],strokeWidth:2,hover:{size:4}},xaxis:{categories:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],axisTicks:{show:!1},axisBorder:{show:!1}},yaxis:{min:0,axisBorder:{show:!1}},grid:{show:!0,strokeDashArray:3,xaxis:{lines:{show:!1}},yaxis:{lines:{show:!0}},padding:{top:0,right:-2,bottom:10,left:10}},legend:{show:!0,horizontalAlign:"center",offsetX:0,offsetY:5,markers:{width:9,height:9,radius:6},itemMargin:{horizontal:10,vertical:0}},plotOptions:{bar:{columnWidth:"30%",barHeight:"70%",borderRadius:3}},colors:["#7e67fe","#17c553","#7942ed"],tooltip:{shared:!0,y:[{formatter:function(e){return typeof e<"u"?e.toFixed(1)+"k":e}},{formatter:function(e){return typeof e<"u"?e.toFixed(1)+"k":e}}]}},o=new t(document.querySelector("#dash-performance-chart"),a);o.render();class n{initWorldMapMarker(){new i({map:"world",selector:"#world-map-markers",zoomOnScroll:!0,zoomButtons:!1,markersSelectable:!0,markers:[{name:"Canada",coords:[56.1304,-106.3468]},{name:"Brazil",coords:[-14.235,-51.9253]},{name:"Russia",coords:[61,105]},{name:"China",coords:[35.8617,104.1954]},{name:"United States",coords:[37.0902,-95.7129]}],markerStyle:{initial:{fill:"#7f56da"},selected:{fill:"#1bb394"}},labels:{markers:{render:s=>s.name}},regionStyle:{initial:{fill:"rgba(169,183,197, 0.3)",fillOpacity:1}}})}init(){this.initWorldMapMarker()}}document.addEventListener("DOMContentLoaded",function(e){new n().init()});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{j as a}from"./world-BH8KG5u4.js";import"./_commonjsHelpers-C4iS2aBk.js";class r{initWorldMapMarker(){new a({map:"world",selector:"#world-map-markers",zoomOnScroll:!1,zoomButtons:!0,markersSelectable:!0,markers:[{name:"Greenland",coords:[72,-42]},{name:"Canada",coords:[56.1304,-106.3468]},{name:"Brazil",coords:[-14.235,-51.9253]},{name:"Egypt",coords:[26.8206,30.8025]},{name:"Russia",coords:[61,105]},{name:"China",coords:[35.8617,104.1954]},{name:"United States",coords:[37.0902,-95.7129]},{name:"Norway",coords:[60.472024,8.468946]},{name:"Ukraine",coords:[48.379433,31.16558]}],markerStyle:{initial:{fill:"#5B8DEC"},selected:{fill:"#ed5565"}},labels:{markers:{render:i=>i.name}},regionStyle:{initial:{fill:"rgba(169,183,197, 0.2)",fillOpacity:1}}})}initCanadaVectorMap(){new a({map:"canada",selector:"#canada-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#1e84c4"}}})}initRussiaVectorMap(){new a({map:"russia",selector:"#russia-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#1bb394"}}})}initIraqVectorMap(){new a({map:"iraq",selector:"#iraq-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#f8ac59"}}})}initSpainVectorMap(){new a({map:"spain",selector:"#spain-vector-map",zoomOnScroll:!1,regionStyle:{initial:{fill:"#23c6c8"}}})}initUsaVectorMap(){new a({map:"us_merc_en",selector:"#usa-vector-map",regionStyle:{initial:{fill:"#ffe381"}}})}init(){this.initWorldMapMarker(),this.initCanadaVectorMap(),this.initRussiaVectorMap(),this.initIraqVectorMap(),this.initSpainVectorMap()}}document.addEventListener("DOMContentLoaded",function(e){new r().init()});
|
||||
File diff suppressed because one or more lines are too long
61
server-setup.sh
Executable file
61
server-setup.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Server setup untuk optimasi memory dan build
|
||||
# Jalankan dengan sudo di server production
|
||||
|
||||
echo "🔧 Setting up server for optimized building..."
|
||||
|
||||
# 1. Check current memory
|
||||
echo "📊 Current memory status:"
|
||||
free -h
|
||||
|
||||
# 2. Setup swap file (temporary solution for low memory)
|
||||
echo "💾 Setting up swap file (1GB)..."
|
||||
if [ ! -f /swapfile ]; then
|
||||
fallocate -l 1G /swapfile
|
||||
chmod 600 /swapfile
|
||||
mkswap /swapfile
|
||||
sysctl vm.swappiness=10
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
echo 'vm.swappiness=10' >> /etc/sysctl.conf
|
||||
swapon /swapfile
|
||||
echo "✅ Swap file created and activated"
|
||||
else
|
||||
echo "ℹ️ Swap file already exists"
|
||||
fi
|
||||
|
||||
# 3. Optimize Node.js for production
|
||||
echo "⚙️ Optimizing Node.js..."
|
||||
npm config set fund false
|
||||
npm config set audit false
|
||||
|
||||
# 4. Install PM2 untuk process management
|
||||
echo "📦 Installing PM2..."
|
||||
npm install -g pm2
|
||||
|
||||
# 5. Create PM2 ecosystem file for build process
|
||||
cat > ecosystem.config.js << 'EOF'
|
||||
module.exports = {
|
||||
apps: [{
|
||||
name: 'build-app',
|
||||
script: 'npm',
|
||||
args: 'run build:prod',
|
||||
instances: 1,
|
||||
autorestart: false,
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
NODE_OPTIONS: '--max-old-space-size=1024'
|
||||
}
|
||||
}]
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Server setup completed!"
|
||||
echo ""
|
||||
echo "📝 Now you can:"
|
||||
echo " 1. Build with memory limit: npm run build:prod"
|
||||
echo " 2. Build with PM2: pm2 start ecosystem.config.js"
|
||||
echo " 3. Monitor: pm2 monit"
|
||||
echo " 4. Check memory: free -h"
|
||||
191
vite.config.production.js
Normal file
191
vite.config.production.js
Normal file
@@ -0,0 +1,191 @@
|
||||
import { defineConfig } from "vite";
|
||||
import laravel from "laravel-vite-plugin";
|
||||
import path from "path";
|
||||
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
hmr: {
|
||||
host: 'localhost'
|
||||
},
|
||||
watch: {
|
||||
usePolling: true
|
||||
}
|
||||
},
|
||||
build: {
|
||||
outDir: 'public/build',
|
||||
assetsDir: 'assets',
|
||||
manifest: true,
|
||||
// Optimasi untuk server dengan resource terbatas
|
||||
minify: 'terser',
|
||||
chunkSizeWarningLimit: 1000,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
// Split vendor chunks untuk mengurangi memory usage
|
||||
vendor: ['bootstrap', 'moment', 'axios'],
|
||||
charts: ['apexcharts'],
|
||||
maps: ['leaflet', 'jsvectormap', 'gmaps'],
|
||||
ui: ['sweetalert2', 'flatpickr', 'quill', 'dropzone'],
|
||||
forms: ['gridjs', 'simplebar'],
|
||||
// Group by functionality to reduce memory usage per chunk
|
||||
dashboards: [
|
||||
'resources/js/dashboards/bigdata.js',
|
||||
'resources/js/dashboards/pbg.js',
|
||||
'resources/js/dashboards/potentials/inside_system.js',
|
||||
'resources/js/dashboards/potentials/outside_system.js'
|
||||
],
|
||||
data: [
|
||||
'resources/js/data/umkm/data-umkm.js',
|
||||
'resources/js/data/tourisms/data-tourisms.js',
|
||||
'resources/js/data/advertisements/data-advertisements.js'
|
||||
]
|
||||
},
|
||||
entryFileNames: 'assets/[name]-[hash].js',
|
||||
chunkFileNames: 'assets/[name]-[hash].js',
|
||||
assetFileNames: 'assets/[name]-[hash].[ext]'
|
||||
},
|
||||
// Optimasi memory - lebih konservatif
|
||||
maxParallelFileOps: 1,
|
||||
},
|
||||
// Compress assets
|
||||
assetsInlineLimit: 4096,
|
||||
// Reduce memory usage
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true,
|
||||
drop_debugger: true
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "resources/js"),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
laravel({
|
||||
input: [
|
||||
//css
|
||||
"resources/scss/icons.scss",
|
||||
"resources/scss/style.scss",
|
||||
"resources/scss/components/_circle.scss",
|
||||
"resources/scss/dashboards/_bigdata.scss",
|
||||
"resources/scss/dashboards/_lack-of-potential.scss",
|
||||
"resources/scss/components/_custom_circle.scss",
|
||||
"resources/scss/dashboards/potentials/_inside_system.scss",
|
||||
"resources/scss/dashboards/potentials/_outside_system.scss",
|
||||
"resources/scss/pages/quick-search/detail.scss",
|
||||
"resources/scss/pages/quick-search/index.scss",
|
||||
"resources/scss/pages/quick-search/result.scss",
|
||||
|
||||
"node_modules/quill/dist/quill.snow.css",
|
||||
"node_modules/quill/dist/quill.bubble.css",
|
||||
"node_modules/flatpickr/dist/flatpickr.min.css",
|
||||
"node_modules/flatpickr/dist/themes/dark.css",
|
||||
"node_modules/gridjs/dist/theme/mermaid.css",
|
||||
"node_modules/flatpickr/dist/themes/dark.css",
|
||||
"node_modules/gridjs/dist/theme/mermaid.min.css",
|
||||
|
||||
//js
|
||||
"resources/js/app.js",
|
||||
"resources/js/config.js",
|
||||
"resources/js/pages/dashboard.js",
|
||||
"resources/js/pages/chart.js",
|
||||
"resources/js/pages/form-quilljs.js",
|
||||
"resources/js/pages/form-fileupload.js",
|
||||
"resources/js/pages/form-flatepicker.js",
|
||||
"resources/js/pages/table-gridjs.js",
|
||||
"resources/js/pages/maps-google.js",
|
||||
"resources/js/pages/maps-vector.js",
|
||||
"resources/js/pages/maps-spain.js",
|
||||
"resources/js/pages/maps-russia.js",
|
||||
"resources/js/pages/maps-iraq.js",
|
||||
"resources/js/pages/maps-canada.js",
|
||||
"resources/js/data/advertisements/data-advertisements.js",
|
||||
"resources/js/data/advertisements/form-create-update.js",
|
||||
"resources/js/data/advertisements/form-upload.js",
|
||||
|
||||
//js-additional
|
||||
"resources/js/settings/syncronize/syncronize.js",
|
||||
"resources/js/settings/general/general-settings.js",
|
||||
"resources/js/tables/common-table.js",
|
||||
|
||||
// dashboards
|
||||
"resources/js/dashboards/bigdata.js",
|
||||
"resources/js/dashboards/potentials/inside_system.js",
|
||||
"resources/js/dashboards/potentials/outside_system.js",
|
||||
// roles
|
||||
"resources/js/roles/index.js",
|
||||
"resources/js/roles/create.js",
|
||||
"resources/js/roles/update.js",
|
||||
"resources/js/roles/role_menu.js",
|
||||
// users
|
||||
"resources/js/master/users/users.js",
|
||||
"resources/js/master/users/create.js",
|
||||
"resources/js/master/users/update.js",
|
||||
// menus
|
||||
"resources/js/menus/index.js",
|
||||
"resources/js/menus/create.js",
|
||||
"resources/js/menus/update.js",
|
||||
//data-settings
|
||||
"resources/js/data-settings/index.js",
|
||||
"resources/js/data-settings/create.js",
|
||||
"resources/js/data-settings/update.js",
|
||||
// business-industries
|
||||
"resources/js/business-industries/create.js",
|
||||
"resources/js/business-industries/update.js",
|
||||
"resources/js/business-industries/index.js",
|
||||
// umkm
|
||||
"resources/js/data/umkm/data-umkm.js",
|
||||
"resources/js/data/umkm/form-upload.js",
|
||||
"resources/js/data/umkm/form-create-update.js",
|
||||
// tourisms
|
||||
"resources/js/data/tourisms/data-tourisms.js",
|
||||
"resources/js/data/tourisms/form-create-update.js",
|
||||
"resources/js/data/tourisms/form-upload.js",
|
||||
"resources/js/report/tourisms/index.js",
|
||||
// spatial-plannings
|
||||
"resources/js/data/spatialPlannings/data-spatialPlannings.js",
|
||||
"resources/js/data/spatialPlannings/form-create-update.js",
|
||||
"resources/js/data/spatialPlannings/form-upload.js",
|
||||
// customers
|
||||
"resources/js/customers/upload.js",
|
||||
"resources/js/customers/index.js",
|
||||
"resources/js/customers/create.js",
|
||||
"resources/js/customers/edit.js",
|
||||
"resources/js/dashboards/pbg.js",
|
||||
// maps
|
||||
"resources/js/maps/maps-kml.js",
|
||||
// laporan pimpinan
|
||||
"resources/js/bigdata-resumes/index.js",
|
||||
"resources/js/chatbot/index.js",
|
||||
"resources/js/chatbot-pimpinan/index.js",
|
||||
//pbg-task
|
||||
"resources/js/pbg-task/index.js",
|
||||
"resources/js/pbg-task/show.js",
|
||||
"resources/js/pbg-task/create.js",
|
||||
// google-sheets
|
||||
"resources/js/data/google-sheet/index.js",
|
||||
// quick-search
|
||||
"resources/js/quick-search/index.js",
|
||||
"resources/js/quick-search/result.js",
|
||||
"resources/js/quick-search/detail.js",
|
||||
// growth-report
|
||||
"resources/js/report/growth-report/index.js",
|
||||
// dummy
|
||||
"resources/js/approval/index.js",
|
||||
"resources/js/invitations/index.js",
|
||||
"resources/js/payment-recaps/index.js",
|
||||
"resources/js/report-pbg-ptsp/index.js",
|
||||
"resources/js/tpa-tpt/index.js",
|
||||
"resources/js/report-payment-recaps/index.js",
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
],
|
||||
// Limit memory usage
|
||||
esbuild: {
|
||||
target: 'es2015'
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user