onelaraveljs 1.0.0 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/onejs-build.js +32 -0
- package/index.js +3 -1
- package/package.json +11 -3
- package/scripts/README-template-compiler.md +133 -0
- package/scripts/README.md +61 -0
- package/scripts/__pycache__/build.cpython-314.pyc +0 -0
- package/scripts/__pycache__/compile.cpython-313.pyc +0 -0
- package/scripts/__pycache__/compile.cpython-314.pyc +0 -0
- package/scripts/build.py +574 -0
- package/scripts/check-system-errors.php +214 -0
- package/scripts/compile.py +101 -0
- package/scripts/compiler/README_CONFIG.md +196 -0
- package/scripts/compiler/__init__.py +18 -0
- package/scripts/compiler/__pycache__/__init__.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/__init__.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/binding_directive_service.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/class_binding_handler.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/compiler_utils.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/compiler_utils.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/conditional_handlers.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/conditional_handlers.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/config.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/config.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/declaration_tracker.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/directive_processors.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/directive_processors.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/echo_processor.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/event_directive_processor.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/event_directive_processor.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/function_generators.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/function_generators.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/loop_handlers.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/loop_handlers.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/main_compiler.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/main_compiler.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/parsers.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/parsers.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/php_converter.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/php_converter.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/php_js_converter.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/php_js_converter.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/register_parser.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/register_parser.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/section_handlers.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/section_handlers.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/show_directive_handler.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/style_directive_handler.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/template_analyzer.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/template_analyzer.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/template_processor.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/template_processor.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/template_processors.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/template_processors.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/utils.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/utils.cpython-314.pyc +0 -0
- package/scripts/compiler/__pycache__/wrapper_parser.cpython-313.pyc +0 -0
- package/scripts/compiler/__pycache__/wrapper_parser.cpython-314.pyc +0 -0
- package/scripts/compiler/binding_directive_service.py +103 -0
- package/scripts/compiler/class_binding_handler.py +347 -0
- package/scripts/compiler/cli.py +34 -0
- package/scripts/compiler/code_generator.py +141 -0
- package/scripts/compiler/compiler.config.json +36 -0
- package/scripts/compiler/compiler_utils.py +55 -0
- package/scripts/compiler/conditional_handlers.py +252 -0
- package/scripts/compiler/config.py +107 -0
- package/scripts/compiler/declaration_tracker.py +420 -0
- package/scripts/compiler/directive_processors.py +603 -0
- package/scripts/compiler/echo_processor.py +667 -0
- package/scripts/compiler/event_directive_processor.py +1099 -0
- package/scripts/compiler/fetch_parser.py +49 -0
- package/scripts/compiler/function_generators.py +310 -0
- package/scripts/compiler/loop_handlers.py +224 -0
- package/scripts/compiler/main_compiler.py +1763 -0
- package/scripts/compiler/parsers.py +1418 -0
- package/scripts/compiler/php_converter.py +470 -0
- package/scripts/compiler/php_js_converter.py +603 -0
- package/scripts/compiler/register_parser.py +480 -0
- package/scripts/compiler/section_handlers.py +122 -0
- package/scripts/compiler/show_directive_handler.py +85 -0
- package/scripts/compiler/style_directive_handler.py +169 -0
- package/scripts/compiler/template_analyzer.py +162 -0
- package/scripts/compiler/template_processor.py +1167 -0
- package/scripts/compiler/template_processors.py +1557 -0
- package/scripts/compiler/test_compiler.py +69 -0
- package/scripts/compiler/utils.py +54 -0
- package/scripts/compiler/variables_analyzer.py +135 -0
- package/scripts/compiler/view_identifier_generator.py +278 -0
- package/scripts/compiler/wrapper_parser.py +78 -0
- package/scripts/dev-context.js +311 -0
- package/scripts/dev.js +109 -0
- package/scripts/generate-assets-order.js +208 -0
- package/scripts/migrate-namespace.php +146 -0
- package/scripts/node/MIGRATION.md +190 -0
- package/scripts/node/README.md +269 -0
- package/scripts/node/build.js +208 -0
- package/scripts/node/compiler/compiler-utils.js +38 -0
- package/scripts/node/compiler/conditional-handlers.js +45 -0
- package/scripts/node/compiler/config.js +178 -0
- package/scripts/node/compiler/directive-processors.js +51 -0
- package/scripts/node/compiler/event-directive-processor.js +182 -0
- package/scripts/node/compiler/function-generators.js +239 -0
- package/scripts/node/compiler/loop-handlers.js +45 -0
- package/scripts/node/compiler/main-compiler.js +236 -0
- package/scripts/node/compiler/parsers.js +358 -0
- package/scripts/node/compiler/php-converter.js +227 -0
- package/scripts/node/compiler/register-parser.js +32 -0
- package/scripts/node/compiler/section-handlers.js +46 -0
- package/scripts/node/compiler/template-analyzer.js +50 -0
- package/scripts/node/compiler/template-processor.js +371 -0
- package/scripts/node/compiler/template-processors.js +219 -0
- package/scripts/node/compiler/utils.js +203 -0
- package/scripts/node/compiler/wrapper-parser.js +25 -0
- package/scripts/node/package.json +24 -0
- package/scripts/node/test-compiler.js +52 -0
- package/scripts/node-run.cjs +28 -0
- package/scripts/standardize-directories.php +92 -0
- package/src/core/ViewManager.js +4 -4
- package/templates/view.module.js +2 -0
- package/templates/view.tpl-raw.js +13 -0
- package/templates/wraper.js +71 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Development Script with Context Support (web/admin)
|
|
5
|
+
* - Watch blade files and JS core files (auto-detect from build.config.json)
|
|
6
|
+
* - Auto-compile templates when changed
|
|
7
|
+
* - Auto-rebuild webpack when JS changed
|
|
8
|
+
* - Run PHP artisan serve
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { spawn } from 'child_process';
|
|
12
|
+
import { watch } from 'fs';
|
|
13
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
import { WebSocketServer } from 'ws';
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = path.dirname(__filename);
|
|
20
|
+
|
|
21
|
+
// Get context from command line argument
|
|
22
|
+
const context = process.argv[2] || 'web'; // Default to 'web'
|
|
23
|
+
|
|
24
|
+
if (!['web', 'admin'].includes(context)) {
|
|
25
|
+
console.error('❌ Invalid context. Use: web or admin');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Load build config
|
|
30
|
+
const buildConfigPath = path.resolve(__dirname, '../build.config.json');
|
|
31
|
+
const buildConfig = JSON.parse(readFileSync(buildConfigPath, 'utf-8'));
|
|
32
|
+
const contextConfig = buildConfig.contexts[context];
|
|
33
|
+
|
|
34
|
+
if (!contextConfig) {
|
|
35
|
+
console.error(`❌ Context "${context}" not found in build.config.json`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const config = {
|
|
40
|
+
context: context,
|
|
41
|
+
watchPaths: {
|
|
42
|
+
blade: contextConfig.sources, // Array of blade source paths from config
|
|
43
|
+
jsCore: 'resources/js/onejs', // Watch entire onejs directory
|
|
44
|
+
jsViewsExclude: 'resources/js/onejs/views', // Exclude views directory
|
|
45
|
+
compiler: 'scripts/compiler'
|
|
46
|
+
},
|
|
47
|
+
buildCommand: `npm run build:${context}`,
|
|
48
|
+
phpServeCommand: 'php artisan serve',
|
|
49
|
+
phpPort: context === 'admin' ? 8001 : 8000,
|
|
50
|
+
wsPort: context === 'admin' ? 3301 : 3300
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
class ContextDevServer {
|
|
54
|
+
constructor() {
|
|
55
|
+
this.processes = {
|
|
56
|
+
phpServe: null
|
|
57
|
+
};
|
|
58
|
+
this.wss = null;
|
|
59
|
+
this.isBuilding = false;
|
|
60
|
+
this.debounceTimer = null;
|
|
61
|
+
this.debounceDelay = 300; // ms
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async start() {
|
|
65
|
+
console.log(`🚀 Starting Development Server for [${config.context.toUpperCase()}] context...\n`);
|
|
66
|
+
|
|
67
|
+
// Initial build (templates + webpack)
|
|
68
|
+
await this.runBuild();
|
|
69
|
+
|
|
70
|
+
// Start PHP artisan serve
|
|
71
|
+
this.startPhpServe();
|
|
72
|
+
|
|
73
|
+
// Start WebSocket server for auto-reload
|
|
74
|
+
this.startWebSocketServer();
|
|
75
|
+
|
|
76
|
+
// Create reload script file
|
|
77
|
+
this.createReloadScript();
|
|
78
|
+
|
|
79
|
+
// Start file watcher for blade and compiler files
|
|
80
|
+
this.startWatcher();
|
|
81
|
+
|
|
82
|
+
console.log('\n✅ Development server started!');
|
|
83
|
+
console.log(`📦 Context: ${config.context.toUpperCase()}`);
|
|
84
|
+
console.log('📝 Watching:');
|
|
85
|
+
console.log(` - Blade files: ${config.watchPaths.blade.join(', ')}`);
|
|
86
|
+
console.log(` - JS Core: ${config.watchPaths.jsCore} (excluding views)`);
|
|
87
|
+
console.log(` - Compiler: ${config.watchPaths.compiler}`);
|
|
88
|
+
console.log(`🌐 Laravel Server: http://localhost:${config.phpPort}`);
|
|
89
|
+
console.log(`🔄 Auto-reload: Active (add script to your layout)`);
|
|
90
|
+
console.log(`⚡ Auto-rebuild: npm run build:${config.context}`);
|
|
91
|
+
console.log('\n💡 Add this to your blade layout:');
|
|
92
|
+
console.log(` <script src="/reload-dev.js"></script>`);
|
|
93
|
+
console.log('\n💡 Press Ctrl+C to stop\n');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async runBuild() {
|
|
97
|
+
if (this.isBuilding) {
|
|
98
|
+
console.log('⏳ Build already in progress, skipping...');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.isBuilding = true;
|
|
103
|
+
console.log(`🔨 Building [${config.context}] (templates + webpack)...`);
|
|
104
|
+
|
|
105
|
+
return new Promise((resolve, reject) => {
|
|
106
|
+
const build = spawn('sh', ['-c', config.buildCommand], {
|
|
107
|
+
stdio: 'inherit',
|
|
108
|
+
cwd: path.resolve(__dirname, '..')
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
build.on('close', (code) => {
|
|
112
|
+
this.isBuilding = false;
|
|
113
|
+
if (code === 0) {
|
|
114
|
+
console.log(`✅ Build completed for [${config.context}]`);
|
|
115
|
+
// Trigger browser reload via WebSocket
|
|
116
|
+
this.notifyReload();
|
|
117
|
+
resolve();
|
|
118
|
+
} else {
|
|
119
|
+
console.error(`❌ Build failed with code ${code}\n`);
|
|
120
|
+
reject(new Error(`Build failed with code ${code}`));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
build.on('error', (err) => {
|
|
125
|
+
this.isBuilding = false;
|
|
126
|
+
console.error('❌ Failed to start build process:', err);
|
|
127
|
+
reject(err);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
startWebSocketServer() {
|
|
133
|
+
console.log(`🔄 Starting WebSocket server on port ${config.wsPort}...\n`);
|
|
134
|
+
|
|
135
|
+
this.wss = new WebSocketServer({ port: config.wsPort });
|
|
136
|
+
|
|
137
|
+
this.wss.on('connection', (ws) => {
|
|
138
|
+
ws.on('error', console.error);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
notifyReload() {
|
|
143
|
+
if (this.wss) {
|
|
144
|
+
console.log('🔄 Reloading browser...\n');
|
|
145
|
+
this.wss.clients.forEach((client) => {
|
|
146
|
+
if (client.readyState === 1) { // OPEN
|
|
147
|
+
client.send('reload');
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
createReloadScript() {
|
|
154
|
+
const scriptContent = `
|
|
155
|
+
(function() {
|
|
156
|
+
if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
|
|
157
|
+
return; // Only run on local development
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const ws = new WebSocket('ws://localhost:${config.wsPort}');
|
|
161
|
+
|
|
162
|
+
ws.onmessage = function(event) {
|
|
163
|
+
if (event.data === 'reload') {
|
|
164
|
+
console.log('[DEV] Reloading page...');
|
|
165
|
+
window.location.reload();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
ws.onerror = function() {
|
|
170
|
+
console.log('[DEV] WebSocket connection failed');
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
ws.onclose = function() {
|
|
174
|
+
// Reconnect after 1 second
|
|
175
|
+
setTimeout(function() {
|
|
176
|
+
window.location.reload();
|
|
177
|
+
}, 1000);
|
|
178
|
+
};
|
|
179
|
+
})();
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
const publicPath = path.resolve(__dirname, '../public/reload-dev.js');
|
|
183
|
+
writeFileSync(publicPath, scriptContent, 'utf-8');
|
|
184
|
+
console.log(`✅ Created reload script at public/reload-dev.js\n`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
startPhpServe() {
|
|
188
|
+
console.log(`🐘 Starting PHP server on port ${config.phpPort}...`);
|
|
189
|
+
|
|
190
|
+
this.processes.phpServe = spawn('php', ['artisan', 'serve', `--port=${config.phpPort}`], {
|
|
191
|
+
stdio: 'inherit',
|
|
192
|
+
cwd: path.resolve(__dirname, '..')
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
this.processes.phpServe.on('error', (err) => {
|
|
196
|
+
console.error('❌ PHP server error:', err);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
this.processes.phpServe.on('close', (code) => {
|
|
200
|
+
if (code !== 0 && code !== null) {
|
|
201
|
+
console.error(`❌ PHP server exited with code ${code}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
startWatcher() {
|
|
207
|
+
// Watch blade files (multiple source directories from config)
|
|
208
|
+
config.watchPaths.blade.forEach(bladePath => {
|
|
209
|
+
console.log(`👀 Watching blade files in: ${bladePath}`);
|
|
210
|
+
watch(bladePath, { recursive: true }, (eventType, filename) => {
|
|
211
|
+
if (filename && filename.endsWith('.blade.php')) {
|
|
212
|
+
this.handleFileChange('blade', path.join(bladePath, filename));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Watch JS core files (entire onejs directory, excluding views)
|
|
218
|
+
console.log(`👀 Watching JS core in: ${config.watchPaths.jsCore} (excluding views)`);
|
|
219
|
+
watch(config.watchPaths.jsCore, { recursive: true }, (eventType, filename) => {
|
|
220
|
+
if (filename && filename.endsWith('.js')) {
|
|
221
|
+
const fullPath = path.join(config.watchPaths.jsCore, filename);
|
|
222
|
+
// Skip if file is in views directory
|
|
223
|
+
if (!fullPath.includes(path.sep + 'views' + path.sep) && !fullPath.endsWith(path.sep + 'views')) {
|
|
224
|
+
this.handleFileChange('js-core', filename);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Watch compiler files
|
|
230
|
+
console.log(`👀 Watching compiler in: ${config.watchPaths.compiler}`);
|
|
231
|
+
watch(config.watchPaths.compiler, { recursive: true }, (eventType, filename) => {
|
|
232
|
+
if (filename && (filename.endsWith('.py') || filename.endsWith('.js'))) {
|
|
233
|
+
this.handleFileChange('compiler', filename);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
handleFileChange(type, filename) {
|
|
239
|
+
// Clear existing timer
|
|
240
|
+
if (this.debounceTimer) {
|
|
241
|
+
clearTimeout(this.debounceTimer);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Debounce to avoid multiple rapid builds
|
|
245
|
+
this.debounceTimer = setTimeout(() => {
|
|
246
|
+
console.log(`\n📝 [${type.toUpperCase()}] File changed: ${filename}`);
|
|
247
|
+
|
|
248
|
+
// Rebuild everything (templates + webpack) for any changes
|
|
249
|
+
this.runBuild().catch(err => {
|
|
250
|
+
console.error('Build error:', err);
|
|
251
|
+
});
|
|
252
|
+
}, this.debounceDelay);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
stop() {
|
|
256
|
+
console.log('\n🛑 Shutting down development server...');
|
|
257
|
+
|
|
258
|
+
// Stop WebSocket Server
|
|
259
|
+
if (this.wss) {
|
|
260
|
+
console.log(' Stopping WebSocket server...');
|
|
261
|
+
this.wss.close();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Kill all processes
|
|
265
|
+
Object.keys(this.processes).forEach(key => {
|
|
266
|
+
const proc = this.processes[key];
|
|
267
|
+
if (proc && !proc.killed) {
|
|
268
|
+
console.log(` Stopping ${key}...`);
|
|
269
|
+
proc.kill('SIGTERM');
|
|
270
|
+
|
|
271
|
+
// Force kill after 2 seconds if not terminated
|
|
272
|
+
setTimeout(() => {
|
|
273
|
+
if (!proc.killed) {
|
|
274
|
+
proc.kill('SIGKILL');
|
|
275
|
+
}
|
|
276
|
+
}, 2000);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
console.log('✅ Development server stopped');
|
|
281
|
+
process.exit(0);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Handle process termination
|
|
286
|
+
process.on('SIGINT', () => {
|
|
287
|
+
if (devServer) {
|
|
288
|
+
devServer.stop();
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
process.on('SIGTERM', () => {
|
|
293
|
+
if (devServer) {
|
|
294
|
+
devServer.stop();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Catch unhandled errors
|
|
299
|
+
process.on('uncaughtException', (err) => {
|
|
300
|
+
console.error('❌ Uncaught exception:', err);
|
|
301
|
+
if (devServer) {
|
|
302
|
+
devServer.stop();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Start development server
|
|
307
|
+
const devServer = new ContextDevServer();
|
|
308
|
+
devServer.start().catch(err => {
|
|
309
|
+
console.error('❌ Failed to start dev server:', err);
|
|
310
|
+
process.exit(1);
|
|
311
|
+
});
|
package/scripts/dev.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Development Script for Blade Compiler
|
|
5
|
+
* Provides development workflow with hot reload
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { watch } from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
|
|
12
|
+
const config = {
|
|
13
|
+
watchPaths: [
|
|
14
|
+
'resources/views',
|
|
15
|
+
'resources/js/app',
|
|
16
|
+
'scripts/compiler'
|
|
17
|
+
],
|
|
18
|
+
buildCommand: 'cd scripts && python3 build.py',
|
|
19
|
+
viteCommand: 'npm run dev'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
class DevServer {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.buildProcess = null;
|
|
25
|
+
this.viteProcess = null;
|
|
26
|
+
this.isBuilding = false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async start() {
|
|
30
|
+
console.log('🚀 Starting Blade Compiler Development Server...\n');
|
|
31
|
+
|
|
32
|
+
// Initial build
|
|
33
|
+
await this.runBuild();
|
|
34
|
+
|
|
35
|
+
// Start Vite dev server
|
|
36
|
+
this.startVite();
|
|
37
|
+
|
|
38
|
+
// Start file watcher
|
|
39
|
+
this.startWatcher();
|
|
40
|
+
|
|
41
|
+
console.log('✅ Development server started!');
|
|
42
|
+
console.log('📝 Watching for changes in:', config.watchPaths.join(', '));
|
|
43
|
+
console.log('🌐 Vite dev server: http://localhost:5173');
|
|
44
|
+
console.log('⚡ Blade compiler: Auto-rebuild on file changes\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async runBuild() {
|
|
48
|
+
if (this.isBuilding) return;
|
|
49
|
+
|
|
50
|
+
this.isBuilding = true;
|
|
51
|
+
console.log('🔨 Building Blade templates...');
|
|
52
|
+
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const build = spawn('sh', ['-c', 'cd scripts && python3 build.py'], {
|
|
55
|
+
stdio: 'inherit',
|
|
56
|
+
cwd: process.cwd()
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
build.on('close', (code) => {
|
|
60
|
+
this.isBuilding = false;
|
|
61
|
+
if (code === 0) {
|
|
62
|
+
console.log('✅ Build completed successfully\n');
|
|
63
|
+
resolve();
|
|
64
|
+
} else {
|
|
65
|
+
console.log('❌ Build failed\n');
|
|
66
|
+
reject(new Error(`Build failed with code ${code}`));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
startVite() {
|
|
73
|
+
this.viteProcess = spawn('npm', ['run', 'dev'], {
|
|
74
|
+
stdio: 'inherit',
|
|
75
|
+
cwd: process.cwd()
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
startWatcher() {
|
|
80
|
+
config.watchPaths.forEach(watchPath => {
|
|
81
|
+
watch(watchPath, { recursive: true }, (eventType, filename) => {
|
|
82
|
+
if (filename && (filename.endsWith('.blade.php') || filename.endsWith('.js'))) {
|
|
83
|
+
console.log(`📝 File changed: ${filename}`);
|
|
84
|
+
this.runBuild().catch(console.error);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
stop() {
|
|
91
|
+
if (this.buildProcess) {
|
|
92
|
+
this.buildProcess.kill();
|
|
93
|
+
}
|
|
94
|
+
if (this.viteProcess) {
|
|
95
|
+
this.viteProcess.kill();
|
|
96
|
+
}
|
|
97
|
+
console.log('🛑 Development server stopped');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Handle process termination
|
|
102
|
+
process.on('SIGINT', () => {
|
|
103
|
+
console.log('\n🛑 Shutting down development server...');
|
|
104
|
+
process.exit(0);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Start development server
|
|
108
|
+
const devServer = new DevServer();
|
|
109
|
+
devServer.start().catch(console.error);
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate assets loading order for HTML
|
|
5
|
+
* Reads webpack build output and creates ordered script tags
|
|
6
|
+
* Supports context-based builds (web, admin, etc.)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
16
|
+
// Load build.config.json from project root
|
|
17
|
+
const projectRoot = process.env.ONEJS_PROJECT_ROOT || process.cwd();
|
|
18
|
+
const configPath = path.join(projectRoot, 'build.config.json');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
var buildConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
22
|
+
} catch (e) {
|
|
23
|
+
console.error(`Error loading build.config.json from ${configPath}:`, e.message);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Get context from environment variable
|
|
28
|
+
const buildContext = process.env.BUILD_CONTEXT || 'web';
|
|
29
|
+
|
|
30
|
+
// Determine static path based on context
|
|
31
|
+
const STATIC_PATH = buildConfig.contexts[buildContext]
|
|
32
|
+
? path.join(projectRoot, path.dirname(buildConfig.contexts[buildContext].dist.bundle))
|
|
33
|
+
: path.join(projectRoot, 'public/static/app');
|
|
34
|
+
|
|
35
|
+
// Determine base URL path for assets
|
|
36
|
+
const BASE_URL = buildConfig.contexts[buildContext]
|
|
37
|
+
? `/static/${buildContext}/js/`
|
|
38
|
+
: '/static/app/';
|
|
39
|
+
|
|
40
|
+
const OUTPUT_FILE = path.join(projectRoot, 'resources/views/partials/assets-scripts.blade.php');
|
|
41
|
+
|
|
42
|
+
function getAssetsByCategory() {
|
|
43
|
+
const assets = {
|
|
44
|
+
runtime: [],
|
|
45
|
+
framework: [],
|
|
46
|
+
main: [],
|
|
47
|
+
other: []
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
if (!fs.existsSync(STATIC_PATH)) {
|
|
52
|
+
console.warn(`⚠️ Static path does not exist: ${STATIC_PATH}`);
|
|
53
|
+
return assets;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const files = fs.readdirSync(STATIC_PATH);
|
|
57
|
+
|
|
58
|
+
files.forEach(file => {
|
|
59
|
+
if (!file.endsWith('.js') || file.endsWith('.map')) return;
|
|
60
|
+
|
|
61
|
+
// Runtime chunk (must load first)
|
|
62
|
+
if (file.startsWith('runtime')) {
|
|
63
|
+
assets.runtime.push(file);
|
|
64
|
+
}
|
|
65
|
+
// Framework chunks (vendor, core libraries)
|
|
66
|
+
else if (file.startsWith('framework-')) {
|
|
67
|
+
assets.framework.push(file);
|
|
68
|
+
}
|
|
69
|
+
// Main chunks (application code)
|
|
70
|
+
else if (file.startsWith('main')) {
|
|
71
|
+
assets.main.push(file);
|
|
72
|
+
}
|
|
73
|
+
// Legacy or other chunks
|
|
74
|
+
else {
|
|
75
|
+
assets.other.push(file);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Sort by filename to ensure consistent order
|
|
80
|
+
Object.keys(assets).forEach(key => {
|
|
81
|
+
assets[key].sort();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return assets;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('Error reading assets:', error);
|
|
87
|
+
return assets;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function generateBladeTemplate(assets) {
|
|
92
|
+
const lines = [
|
|
93
|
+
'{{-- Auto-generated webpack assets --}}',
|
|
94
|
+
`{{-- Context: ${buildContext} --}}`,
|
|
95
|
+
'{{-- Generated at: ' + new Date().toISOString() + ' --}}',
|
|
96
|
+
'{{-- Load order: runtime → framework → main --}}',
|
|
97
|
+
''
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// Runtime chunk (must load first)
|
|
101
|
+
if (assets.runtime.length > 0) {
|
|
102
|
+
lines.push('{{-- Runtime chunk (webpack runtime) --}}');
|
|
103
|
+
assets.runtime.forEach(file => {
|
|
104
|
+
lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
105
|
+
});
|
|
106
|
+
lines.push('');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Framework chunks (vendor dependencies)
|
|
110
|
+
if (assets.framework.length > 0) {
|
|
111
|
+
lines.push('{{-- Framework chunks (vendor dependencies) --}}');
|
|
112
|
+
assets.framework.forEach(file => {
|
|
113
|
+
lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
114
|
+
});
|
|
115
|
+
lines.push('');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Main application chunks
|
|
119
|
+
if (assets.main.length > 0) {
|
|
120
|
+
lines.push('{{-- Main application chunks --}}');
|
|
121
|
+
assets.main.forEach(file => {
|
|
122
|
+
lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Other chunks (if any)
|
|
127
|
+
if (assets.other.length > 0) {
|
|
128
|
+
lines.push('');
|
|
129
|
+
lines.push('{{-- Other chunks --}}');
|
|
130
|
+
assets.other.forEach(file => {
|
|
131
|
+
lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return lines.join('\n');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function generateHTMLTemplate(assets) {
|
|
139
|
+
console.log('\n📋 **HTML Script Tags (in loading order):**\n');
|
|
140
|
+
|
|
141
|
+
if (assets.runtime.length > 0) {
|
|
142
|
+
console.log('<!-- Runtime chunk (webpack runtime) -->');
|
|
143
|
+
assets.runtime.forEach(file => {
|
|
144
|
+
console.log(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (assets.framework.length > 0) {
|
|
149
|
+
console.log('<!-- Framework chunks -->');
|
|
150
|
+
assets.framework.forEach(file => {
|
|
151
|
+
console.log(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (assets.main.length > 0) {
|
|
156
|
+
console.log('<!-- Main chunks -->');
|
|
157
|
+
assets.main.forEach(file => {
|
|
158
|
+
console.log(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (assets.other.length > 0) {
|
|
163
|
+
console.log('<!-- Other chunks -->');
|
|
164
|
+
assets.other.forEach(file => {
|
|
165
|
+
console.log(`<script src="${BASE_URL}${file}" defer></script>`);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log('\n💡 **Usage in your layout:**'); console.log('');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function main() {
|
|
173
|
+
console.log('🔍 Analyzing webpack assets...');
|
|
174
|
+
|
|
175
|
+
const assets = getAssetsByCategory();
|
|
176
|
+
|
|
177
|
+
const totalFiles = Object.values(assets).flat().length;
|
|
178
|
+
|
|
179
|
+
console.log('📊 **Assets Summary:**');
|
|
180
|
+
console.log(`- Runtime chunks: ${assets.runtime.length}`);
|
|
181
|
+
console.log(`- Framework chunks: ${assets.framework.length}`);
|
|
182
|
+
console.log(`- Main chunks: ${assets.main.length}`);
|
|
183
|
+
console.log(`- Other chunks: ${assets.other.length}`);
|
|
184
|
+
console.log(`- Total JS files: ${totalFiles}`);
|
|
185
|
+
|
|
186
|
+
// Generate Blade template
|
|
187
|
+
const bladeContent = generateBladeTemplate(assets);
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
fs.writeFileSync(OUTPUT_FILE, bladeContent);
|
|
191
|
+
console.log(`✅ Generated Blade template: ${OUTPUT_FILE}`);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('❌ Error writing Blade template:', error);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Show HTML version
|
|
197
|
+
generateHTMLTemplate(assets);
|
|
198
|
+
|
|
199
|
+
console.log('💡 **Usage in your layout:**');
|
|
200
|
+
console.log('@include("partials.assets-scripts")');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Run if this is the main module
|
|
204
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
205
|
+
main();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { getAssetsByCategory, generateBladeTemplate };
|