Last active
May 27, 2025 20:18
-
-
Save Ghepes/82afa6532b78a53c49dff3463ff6dae3 to your computer and use it in GitHub Desktop.
Dynamic concatenation of JavaScript files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| To change the method to comment out any files before starting the JS script ... | |
| and to also have the hash file name + reading *.*.js and special characters : the following method applies | |
| --- | |
| ### index.js | |
| const express = require('express'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const crypto = require('crypto'); | |
| const app = express(); | |
| // Middleware pentru a gestiona TOATE fișierele JS (inclusiv cele cu caractere speciale în URL) | |
| app.get(/^\/(.+\.js)(?:\+(.+\.js))*$/, (req, res) => { | |
| try { | |
| const requestedPath = decodeURIComponent(req.path); | |
| const files = requestedPath.split('+') | |
| .filter(f => f.endsWith('.js')) | |
| .map(f => f.replace(/^\//, '')); | |
| if (files.length === 0) { | |
| return res.status(400).send('No valid JS files requested'); | |
| } | |
| let output = ''; | |
| const missingFiles = []; | |
| for (const file of files) { | |
| const filePath = path.join(__dirname, 'public', file); | |
| if (fs.existsSync(filePath)) { | |
| const fileHash = crypto.createHash('md5').update(file).digest('hex').substring(0, 16); | |
| output += `;// __FILE_CONTENT_FOR__:${fileHash}.js\n`; | |
| output += fs.readFileSync(filePath, 'utf8').trim() + '\n\n'; | |
| } else { | |
| missingFiles.push(file); | |
| } | |
| } | |
| if (missingFiles.length > 0) { | |
| return res.status(404).send(`Missing files: ${missingFiles.join(', ')}`); | |
| } | |
| res.setHeader('Content-Type', 'application/javascript'); | |
| res.setHeader('Cache-Control', 'public, max-age=86400'); | |
| res.send(output); | |
| } catch (err) { | |
| res.status(500).send(`Error: ${err.message}`); | |
| } | |
| }); | |
| // Fallback | |
| app.use((req, res) => { | |
| res.status(404).send('Not found'); | |
| }); | |
| app.listen(3000, () => { | |
| console.log('Server running at http://localhost:3000'); | |
| }); | |
| --- | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| project-root/ | |
| ├── index.js <-- Server Express | |
| ├── public/ <-- This is where you put all your JS files. | |
| │ ├── one.js | |
| │ ├── two.js | |
| │ ├── three.js | |
| └── package.json | |
| --- | |
| npm init => entry point: (index.js) | |
| npm install express | |
| npm install --save-dev nodemon | |
| Then you can run in development mode with: | |
| bash | |
| npm run dev | |
| Or in production mode with: | |
| bash | |
| npm start | |
| Additional recommendations: | |
| You might want to add error handling middleware to your Express app | |
| Consider adding compression middleware for the JS files: | |
| bash | |
| npm install compression | |
| For production, you might want to add: | |
| json | |
| "engines": { | |
| "node": ">=18.0.0" | |
| } | |
| --- | |
| ### package.json : | |
| { | |
| "name": "myapp", | |
| "version": "1.0.0", | |
| "description": "A server that combines multiple JS files on demand", | |
| "license": "ISC", | |
| "author": "Your Name <[email protected]>", | |
| "type": "commonjs", | |
| "main": "index.js", | |
| "scripts": { | |
| "start": "node index.js", | |
| "dev": "nodemon index.js", | |
| "test": "echo \"Error: no test specified\" && exit 1" | |
| }, | |
| "dependencies": { | |
| "express": "^5.1.0" | |
| }, | |
| "devDependencies": { | |
| "nodemon": "^3.1.0" | |
| } | |
| } | |
| --- | |
| ### index.js | |
| const express = require('express'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const app = express(); | |
| // Serve static files normally | |
| app.use(express.static(path.join(__dirname, 'public'))); | |
| // Handle JS file combinations | |
| app.get(/^\/([a-zA-Z0-9_-]+\.js\+)+[a-zA-Z0-9_-]+\.js$/, (req, res) => { | |
| const requestedPath = decodeURIComponent(req.path); | |
| const files = requestedPath | |
| .split('+') | |
| .map(f => f.replace(/^\//, '')) // Remove leading slash | |
| .filter(f => f.endsWith('.js')); // Only process .js files | |
| // If no valid JS files found | |
| if (files.length === 0) { | |
| return res.status(400).send('No valid JS files requested'); | |
| } | |
| let output = ''; | |
| let missingFiles = []; | |
| try { | |
| for (const file of files) { | |
| const filePath = path.join(__dirname, 'public', file); | |
| if (fs.existsSync(filePath)) { | |
| output += fs.readFileSync(filePath, 'utf8') + '\n;\n'; | |
| } else { | |
| missingFiles.push(file); | |
| } | |
| } | |
| if (missingFiles.length > 0) { | |
| return res.status(404).send(`Missing files: ${missingFiles.join(', ')}`); | |
| } | |
| res.setHeader('Content-Type', 'application/javascript'); | |
| res.setHeader('Cache-Control', 'public, max-age=86400'); | |
| res.send(output); | |
| } catch (err) { | |
| res.status(500).send('Error processing files'); | |
| } | |
| }); | |
| // Fallback for other routes | |
| app.use((req, res) => { | |
| res.status(404).send('Not found'); | |
| }); | |
| app.listen(3000, () => { | |
| console.log('Server running at http://localhost:3000'); | |
| }); | |
| --- | |
| ls /public | |
| one.js => One | |
| two.js => Two | |
| three.js => Three | |
| --- | |
| npm run start | |
| ### http://localhost:3000/ | |
| ## GO To | |
| ### http://localhost:3000/one.js+two.js+three.js | |
| --- | |
| ONE | |
| ; | |
| TWO | |
| ; | |
| THREE | |
| ; | |
| --- | |
| Or | |
| ### http://localhost:3000/one.js+two.js | |
| ONE | |
| ; | |
| TWO | |
| ; | |
| --- | |
| You can apply methods like this <script src="http://localhost:3000/one.js+two.js+three.js"></script> | |
| <script src="http://localhost:3000/one.js+two.js"></script> | |
| <script src="http://localhost:3000/one.js"></script> | |
| --- | |
| Happy End | |
| LG | |
Author
Ghepes
commented
May 27, 2025

Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment



