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
| 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 | |
| ; | |
| --- | |
| Happy End | |
| LG | |
Author
Ghepes
commented
May 27, 2025

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



