Skip to content

Instantly share code, notes, and snippets.

@Ghepes
Last active May 27, 2025 20:18
Show Gist options
  • Save Ghepes/82afa6532b78a53c49dff3463ff6dae3 to your computer and use it in GitHub Desktop.
Save Ghepes/82afa6532b78a53c49dff3463ff6dae3 to your computer and use it in GitHub Desktop.
Dynamic concatenation of JavaScript files
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');
});
---
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
@Ghepes
Copy link
Author

Ghepes commented May 27, 2025

Screenshot 2025-05-27 191611

@Ghepes
Copy link
Author

Ghepes commented May 27, 2025

image
image

@Ghepes
Copy link
Author

Ghepes commented May 27, 2025

the method to comment out any files before starting the JS script ...
and to also have the hash file name
image
image

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