Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
akaritakai committed Mar 10, 2022
0 parents commit 1c3f7f6
Show file tree
Hide file tree
Showing 36 changed files with 6,601 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
node_modules
yarn.lock
output
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# www.akaritakai.net
The code that generates https://akaritakai.net/

The project was inspired by [this blog post](https://christine.website/blog/new-language-blog-backend-2022-03-02). The
site's style was inspired by the same site using modified code from
[this repository](https://github.com/Xe/site/tree/e4786467dfc7ec770d4b18e46ee52d2d71f11ba9) under the
[zlib license](https://github.com/Xe/site/blob/e4786467dfc7ec770d4b18e46ee52d2d71f11ba9/LICENSE).

It is deployed via GitHub Actions and Terraform in [this repo](https://github.com/akaritakai/terraform).
Binary file added assets/img/avatar-vacation-large.webp
Binary file not shown.
Binary file added assets/img/avatar-vacation.webp
Binary file not shown.
Binary file added assets/img/sudoku-1.webp
Binary file not shown.
93 changes: 93 additions & 0 deletions build/compileMaps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import fs from "fs";
import glob from "glob";
import grayMatter from 'gray-matter';
import gulp from 'gulp';
import path from "path";
import RSS from 'rss';
import { SitemapStream, streamToPromise } from 'sitemap';
import { Readable } from 'stream';

import {createDirectory, mapsCompileDir, markdownDir} from "./paths.js";

/*
* Now, we want to iterate through all the markdown files and read their paths.
*/
const markdown = [];
function readAllMarkdownFiles(callback) {
const files = glob.sync(path.join(markdownDir, "**/*.md"));
files.forEach((file) => {
const data = fs.readFileSync(file);
const result = grayMatter(data.toString());
markdown.push(result);
});
callback();
}

const now = new Date();

/*
* We want to generate the sitemap
*/
function generateSitemap(callback) {
const links = [];
markdown.forEach((file) => {
const date = file.data.date || now.toISOString();
const link = {
url: file.data.path,
changefreq: 'daily',
lastmod: date
};
links.push(link);
});
const stream = new SitemapStream({
hostname: 'https://akaritakai.net/',
xmlns: {
news: false,
xhtml: false,
image: false,
video: false
}
});
streamToPromise(Readable.from(links).pipe(stream))
.then((result) => {
fs.writeFileSync(path.join(mapsCompileDir, 'sitemap.xml'), result);
callback();
})
.catch((err) => {
callback(err);
});
}

/*
* We want to generate the RSS feed
*/
function generateRss(callback) {
// Format a date like 'May 20, 2012 04:00:00 GMT' for 'now'
const feed = new RSS({
title: "Justin's Blog",
description: "Blog posts by Justin",
feed_url: 'https://akaritakai.net/rss.xml',
site_url: 'https://akaritakai.net/blog/',
pubDate: now,
language: 'en-US',
ttl: 1440,
});
markdown.forEach((file) => {
if (file.data.blog) {
feed.item({
title: file.data.title,
description: file.data.description,
url: `https://akaritakai.net${file.data.path}`,
categories: file.data.tags,
date: file.data.date,
});
}
});
fs.writeFileSync(path.join(mapsCompileDir, 'rss.xml'), feed.xml());
callback();
}

export default gulp.series(
gulp.parallel(createDirectory(mapsCompileDir), readAllMarkdownFiles),
gulp.parallel(generateSitemap, generateRss)
);
67 changes: 67 additions & 0 deletions build/compileScripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import chalk from "chalk";
import gulp from 'gulp';
import path from "path";
import TerserJsPlugin from "terser-webpack-plugin";
import webpack from "webpack";

import {createDirectory, scriptCompileDir, scriptDir} from "./paths.js";

function compileScripts(callback) {
const config = {
mode: 'production',
entry: path.resolve(scriptDir, 'index.js'),
output: {
path: scriptCompileDir,
filename: 'site.js'
},
optimization: {
minimize: true,
minimizer: [
new TerserJsPlugin({
terserOptions: {
compress: true,
format: {
comments: false
},
mangle: true,
},
extractComments: false
})
]
},
module: {
rules: [
{
test: /\.js$/i,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
compact: true
}
}
]
}
};
webpack(config, (err, stats) => {
if (err) {
console.log(chalk.red(err));
return callback(err);
}
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}));
if (stats.hasErrors()) {
return callback(new Error('Script build failed with errors.'));
}
callback();
});
}

export default gulp.series(
createDirectory(scriptCompileDir),
compileScripts
);
68 changes: 68 additions & 0 deletions build/compileStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import chalk from "chalk";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import gulp from 'gulp';
import path from "path";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import webpack from "webpack";

import {createDirectory, removePath, styleCompileDir, styleDir} from "./paths.js";

function compileStyles(callback) {
const config = {
mode: 'production',
entry: {
style: path.resolve(styleDir, 'index.scss')
},
output: {
path: styleCompileDir,
filename: 'style.js'
},
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin()
]
},
module: {
rules: [
{
test: /\.scss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'style.css'
})
]
};
webpack(config, (err, stats) => {
if (err) {
console.log(chalk.red(err));
return callback(err);
}
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}));
if (stats.hasErrors()) {
return callback(new Error('Style build failed with errors.'));
}
callback();
});
}

export default gulp.series(
createDirectory(styleCompileDir),
compileStyles,
removePath(path.resolve(styleCompileDir, 'style.js'))
);
89 changes: 89 additions & 0 deletions build/compileTemplates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import chalk from "chalk";
import fs from "fs";
import glob from 'glob';
import gulp from 'gulp';
import HtmlWebpackPlugin from "html-webpack-plugin";
import path from "path";
import webpack from "webpack";

import {createDirectory, emptyJsPath, removePath, templateCompileDir, templateRenderDir} from "./paths.js";
import renderTemplates from "./renderTemplates.js";

function compileTemplates(callback) {
const files = glob.sync(path.join(templateRenderDir, "**/index.html"));
const promises = [];
files.forEach((inputFile) => {
const relativeFile = path.relative(templateRenderDir, inputFile);
const outputFile = path.join(templateCompileDir, relativeFile);
fs.mkdirSync(path.dirname(outputFile), { recursive: true });
const config = {
mode: 'production',
entry: emptyJsPath,
output: {
path: path.dirname(outputFile),
filename: 'index.js'
},
optimization: {
minimize: true
},
plugins: [
new HtmlWebpackPlugin({
template: inputFile,
filename: 'index.html',
inject: false,
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
html5: true,
minifyCSS: true,
minifyJS: true,
removeComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortAttributes: true,
sortClassName: true,
useShortDoctype: true
}
})
]
};
promises.push(new Promise((resolve, reject) => {
webpack(config, (err, stats) => {
if (err) {
reject(err);
} else {
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}));
if (stats.hasErrors()) {
reject(new Error('Template compilation build failed with errors.'));
} else {
fs.rmSync(path.join(path.dirname(outputFile), 'index.js'));
resolve();
}
}
});
}));
Promise.all(promises)
.then(() =>{
callback();
})
.catch((err) => {
console.error(chalk.red(err));
callback(err);
});
});
}

export default gulp.series(
gulp.parallel(
createDirectory(templateCompileDir),
renderTemplates),
compileTemplates
);
Empty file added build/empty.js
Empty file.
Loading

0 comments on commit 1c3f7f6

Please sign in to comment.