add dev server
This commit is contained in:
parent
51afb63f1d
commit
166c3cf0e8
@ -9,6 +9,7 @@ Welcome to the LinkMeUp project! This is a sleek, lightweight single-page applic
|
|||||||
- **Handlebars Templating**: Pre-compiled Handlebars templates for a JavaScript-free frontend.
|
- **Handlebars Templating**: Pre-compiled Handlebars templates for a JavaScript-free frontend.
|
||||||
- **Optimized Performance**: Minimized CSS and HTML files, and optimized images for lightning-fast loading.
|
- **Optimized Performance**: Minimized CSS and HTML files, and optimized images for lightning-fast loading.
|
||||||
- **Accessibility and SEO**: Adherence to web accessibility standards and SEO-friendly structure.
|
- **Accessibility and SEO**: Adherence to web accessibility standards and SEO-friendly structure.
|
||||||
|
- **Development Server**: Develop and view the changes on your page in high speed.
|
||||||
|
|
||||||
## Organizing the Files
|
## Organizing the Files
|
||||||
```
|
```
|
||||||
@ -34,6 +35,11 @@ To get started with the project:
|
|||||||
3. Install dependencies (if any): `pnpm install`
|
3. Install dependencies (if any): `pnpm install`
|
||||||
|
|
||||||
## Building and Deployment
|
## Building and Deployment
|
||||||
|
Develope the project using our development script:
|
||||||
|
```bash
|
||||||
|
pnpm run dev
|
||||||
|
```
|
||||||
|
|
||||||
Build the project using our script:
|
Build the project using our script:
|
||||||
```bash
|
```bash
|
||||||
pnpm run build
|
pnpm run build
|
||||||
|
34
build.js
34
build.js
@ -55,7 +55,20 @@ function copyImages(srcDir, destDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile Handlebars Template
|
function compileHeaderTemplate(data) {
|
||||||
|
const headerTemplatePath = path.join(__dirname, 'src', 'templates', 'header-template.hbs');
|
||||||
|
const headerTemplateSource = readFile(headerTemplatePath);
|
||||||
|
const headerTemplate = handlebars.compile(headerTemplateSource);
|
||||||
|
return headerTemplate(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function compileFooterTemplate(data) {
|
||||||
|
const footerTemplatePath = path.join(__dirname, 'src', 'templates', 'footer-template.hbs');
|
||||||
|
const footerTemplateSource = readFile(footerTemplatePath);
|
||||||
|
const footerTemplate = handlebars.compile(footerTemplateSource);
|
||||||
|
return footerTemplate(data);
|
||||||
|
}
|
||||||
|
|
||||||
function compileTemplate(templatePath, data) {
|
function compileTemplate(templatePath, data) {
|
||||||
const templateSource = readFile(templatePath);
|
const templateSource = readFile(templatePath);
|
||||||
const template = handlebars.compile(templateSource);
|
const template = handlebars.compile(templateSource);
|
||||||
@ -65,12 +78,14 @@ function compileTemplate(templatePath, data) {
|
|||||||
// Main build function
|
// Main build function
|
||||||
function build() {
|
function build() {
|
||||||
const baseHtmlPath = path.join(__dirname, 'public', 'index.html');
|
const baseHtmlPath = path.join(__dirname, 'public', 'index.html');
|
||||||
const templatePath = path.join(__dirname, 'src', 'templates', 'social-links-template.hbs');
|
|
||||||
const dataPath = path.join(__dirname, 'src', 'data.json');
|
const dataPath = path.join(__dirname, 'src', 'data.json');
|
||||||
const cssPath = path.join(__dirname, 'public', 'styles', 'main.css');
|
const cssPath = path.join(__dirname, 'public', 'styles', 'main.css');
|
||||||
const imagesSrcPath = path.join(__dirname, 'public', 'images');
|
const imagesSrcPath = path.join(__dirname, 'public', 'images');
|
||||||
const distPath = path.join(__dirname, 'dist');
|
const distPath = path.join(__dirname, 'dist');
|
||||||
const imagesDestPath = path.join(distPath, 'images');
|
const imagesDestPath = path.join(distPath, 'images');
|
||||||
|
const headerTemplatePath = path.join(__dirname, 'src', 'templates', 'header-template.hbs');
|
||||||
|
const linksTemplatePath = path.join(__dirname, 'src', 'templates', 'social-links-template.hbs');
|
||||||
|
const footerTemplatePath = path.join(__dirname, 'src', 'templates', 'footer-template.hbs');
|
||||||
|
|
||||||
cleanDistDir(distPath);
|
cleanDistDir(distPath);
|
||||||
|
|
||||||
@ -79,6 +94,11 @@ function build() {
|
|||||||
const baseHtml = readFile(baseHtmlPath);
|
const baseHtml = readFile(baseHtmlPath);
|
||||||
let css = readFile(cssPath);
|
let css = readFile(cssPath);
|
||||||
|
|
||||||
|
// Get the current year
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
// Pass the current year to the Handlebars data
|
||||||
|
data.currentYear = currentYear;
|
||||||
|
|
||||||
// Output titles from data.json
|
// Output titles from data.json
|
||||||
data.socialLinks.forEach(link => console.log(link.name));
|
data.socialLinks.forEach(link => console.log(link.name));
|
||||||
|
|
||||||
@ -86,10 +106,16 @@ function build() {
|
|||||||
css = minimizeCSS(css);
|
css = minimizeCSS(css);
|
||||||
|
|
||||||
// Compile HTML with Handlebars
|
// Compile HTML with Handlebars
|
||||||
const socialLinksHtml = compileTemplate(templatePath, data);
|
const headerHtml = compileTemplate(headerTemplatePath, data);
|
||||||
|
const socialLinksHtml = compileTemplate(linksTemplatePath, data);
|
||||||
|
const footerHtml = compileTemplate(footerTemplatePath, data);
|
||||||
|
|
||||||
// Replace placeholder in base HTML with compiled HTML
|
// Replace placeholder in base HTML with compiled HTML
|
||||||
let finalHtml = baseHtml.replace('<!-- Handlebars template will populate this section -->', socialLinksHtml);
|
let finalHtml = baseHtml
|
||||||
|
.replace('<!-- Header template will populate this section -->', headerHtml)
|
||||||
|
.replace('<!-- Handlebars template will populate this section -->', socialLinksHtml)
|
||||||
|
.replace('<!-- Footer template will populate this section -->', footerHtml);
|
||||||
|
|
||||||
|
|
||||||
finalHtml = inlineCSS(finalHtml, css);
|
finalHtml = inlineCSS(finalHtml, css);
|
||||||
finalHtml = minimizeHTML(finalHtml);
|
finalHtml = minimizeHTML(finalHtml);
|
||||||
|
39
dev-server.js
Normal file
39
dev-server.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const chokidar = require('chokidar');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
const browserSync = require('browser-sync').create();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const port = 3000;
|
||||||
|
|
||||||
|
app.use(express.static('dist'));
|
||||||
|
|
||||||
|
const watcher = chokidar.watch(['src', 'public'], { ignored: /(^|[/\\])\../ });
|
||||||
|
|
||||||
|
watcher.on('change', (path) => {
|
||||||
|
console.log(`File ${path} changed. Reloading...`);
|
||||||
|
exec('npm run build', (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`Error: ${error.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
console.error(`Stderr: ${stderr}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(`Build Output: ${stdout}`);
|
||||||
|
browserSync.reload(); // Reload the browser after the build is complete
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Development server is running at http://localhost:${port}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize Browser Sync
|
||||||
|
browserSync.init({
|
||||||
|
proxy: 'http://localhost:3000', // Proxy to the Express server
|
||||||
|
files: 'dist/**/*.*', // Watch files in the dist directory
|
||||||
|
open: false, // Do not open a new browser window
|
||||||
|
notify: false // Do not show notifications
|
||||||
|
});
|
@ -4,6 +4,7 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"dev": "node dev-server.js",
|
||||||
"build": "node build.js",
|
"build": "node build.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
@ -11,7 +12,10 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"browser-sync": "^3.0.2",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
"clean-css": "^5.3.3",
|
"clean-css": "^5.3.3",
|
||||||
|
"express": "^4.18.2",
|
||||||
"handlebars": "^4.7.8",
|
"handlebars": "^4.7.8",
|
||||||
"html-minifier": "^4.0.0"
|
"html-minifier": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
1238
pnpm-lock.yaml
1238
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,21 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LinkMeUp</title>
|
<title>LinkMeUp</title>
|
||||||
<link rel="stylesheet" href="styles/main.css">
|
<link rel="stylesheet" href="styles/main.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<!-- Header template will populate this section -->
|
||||||
<h1>LinkMeUp</h1>
|
<main>
|
||||||
</header>
|
<hr/>
|
||||||
<main id="social-links">
|
|
||||||
<!-- Handlebars template will populate this section -->
|
<!-- Handlebars template will populate this section -->
|
||||||
|
<hr/>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<!-- Footer template will populate this section -->
|
||||||
<p>© 2024 <a href="https://wieerwill.de">WieErWill</a></p>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
3
src/templates/footer-template.hbs
Normal file
3
src/templates/footer-template.hbs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<footer>
|
||||||
|
<p>© {{{footer.copyright}}} {{currentYear}}</p>
|
||||||
|
</footer>
|
6
src/templates/header-template.hbs
Normal file
6
src/templates/header-template.hbs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<header>
|
||||||
|
<h1>{{header.title}}</h1>
|
||||||
|
{{#if header.subtitle}}
|
||||||
|
<h2>{{header.subtitle}}</h2>
|
||||||
|
{{/if}}
|
||||||
|
</header>
|
@ -1,6 +1,12 @@
|
|||||||
{{#each socialLinks}}
|
<div class="link-grid">
|
||||||
<div class="social-link">
|
{{#each socialLinks}}
|
||||||
|
<div class="link" style="background-color: {{backgroundColor}}; color: {{textColor}}">
|
||||||
|
<a href="{{url}}" target="_blank">
|
||||||
|
{{#if icon}}
|
||||||
|
<img src="/images/{{icon}}" alt="{{name}} icon" class="link-icon">
|
||||||
|
{{/if}}
|
||||||
<h2>{{name}}</h2>
|
<h2>{{name}}</h2>
|
||||||
<a href="{{url}}" target="_blank">Visit {{name}}</a>
|
</a>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
|
Loading…
Reference in New Issue
Block a user