Skip to content

Commit

Permalink
Add image optimisation
Browse files Browse the repository at this point in the history
  • Loading branch information
astronomersiva committed Dec 1, 2018
1 parent 42d5eb8 commit dff8b18
Show file tree
Hide file tree
Showing 7 changed files with 1,556 additions and 48 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This was a great learning experience to be honest.
* Supports Liquid templates.
* Supports minification and uglification of JS and CSS file(with `.browserlist.rc`).
* Does asset revision of CSS and JS files.
* JPG and PNG images under `static` will be optimised with `imageoptim`.
* Generates images for various resolutions and automatically inserts `picture` elements with the corresponding `source` elements.
* Minifies output HTML.
* Supports including html in md by implementing a custom md syntax. `::: include table.html :::`.
Expand Down Expand Up @@ -64,7 +65,7 @@ This was a great learning experience to be honest.
```
::: lego-image src="static/images/${IMAGE}" res="1080,500,320" alt="alternate text" class="img-responsive center-block" :::
```
* lego also exposes a `isDevelopment` variable that you can use to disable certain analytics.
* lego also exposes a `isDevelopment` variable that you can use to disable certain stuff in development. For example, analytics.
For example,
```
{% unless isDevelopment %}
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Lego</title><meta name="description" content="Lego, an opinionated static site generator built on NodeJS"><meta content="IE=edge" http-equiv="X-UA-Compatible"><link rel="apple-touch-icon" sizes="180x180" href="static/images/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="static/images/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="static/images/favicon-16x16.png"><link rel="manifest" href="static/images/site.webmanifest"><link rel="mask-icon" href="static/images/safari-pinned-tab.svg" color="#5bbad5"><link rel="shortcut icon" href="static/images/favicon.ico"><meta name="msapplication-TileColor" content="#da532c"><meta name="msapplication-config" content="static/images/browserconfig.xml"><meta name="theme-color" content="#ffffff"><meta name="keywords" content="lego,static site generator,nodejs"><meta name="author" content="Sivasubramanyam A"><meta name="viewport" content="width=device-width,initial-scale=1"><link href="static/css/styles-e2fbcc6720.css" rel="stylesheet"><link href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,700" rel="stylesheet"></head><body><div class="navbar">LEGO</div><main role="main"><div class="container"><h2 class="text-center">Lego is an opinionated static site generator built with NodeJS.</h2><div class="section"><div>Having written several build tools at work over the last few years, I wanted to try my hands at rolling out a full featured static site generator. This is turning out to be a great learning experience and I hope to blog about this soon.</div></div><div class="section"><h3>Features</h3><ul><li>Uses Liquid as the templating engine.</li><li>Supports Markdown files with YAML front-matter.</li><li>Minifies and uglifies JS and CSS files with a specified <span><pre>.browserlist.rc</pre></span>.</li><li>Does asset revision of CSS and JS files.</li><li>Minifies output HTML.</li><li>Live-reload during development.</li><li>Supports including html in md by implementing a custom md syntax. For example, to include a table, <span><pre>::: include table.html :::</pre></span></li><li>Generates images for various resolutions and automatically inserts <span><pre>picture</pre></span>elements with the corresponding <span><pre>source</pre></span>elements.</li><li>Copies CNAME to build directory, so will work with GH Pages with a custom domain.</li><li>🚧 LESS and Sass support.</li><li>🚧 Extracting and inlining critical CSS.</li><li>🚧 Generating sitemaps.</li></ul></div><div class="section"><h3>Installation</h3><div>Run <span><pre>npm i -g @astronomersiva/lego</pre></span>.</div></div><div class="section"><h3>Usage</h3><ul><li>To create a new project, run <span><pre>lego g siteName</pre></span>.</li><li>To start the development server, run <span><pre>lego s</pre></span>.</li><li>To create an optimised build for deployment, run <span><pre>lego</pre></span>.</li><li>To include an HTML in a markdown file, use <span><pre>::: include table.html :::</pre></span>.</li><li>To automatically generate images for various resolutions,<br><code>::: lego-image src="/static/images/${IMAGE}" res="1080,500,320" alt="alternate text" class="img-responsive center-block" :::</code>.</li><li>lego also exposes a <span><pre>isDevelopment</pre></span>variable that you can use to disable certain analytics. For example,<br><code>&#123;% unless isDevelopment %} &lt;!-- analytics code --&gt; &#123;% endunless %}</code></li></ul></div><div class="section"><h3>Directory Structure</h3><pre>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Lego</title><meta name="description" content="Lego, an opinionated static site generator built on NodeJS"><meta content="IE=edge" http-equiv="X-UA-Compatible"><link rel="apple-touch-icon" sizes="180x180" href="static/images/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="static/images/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="static/images/favicon-16x16.png"><link rel="manifest" href="static/images/site.webmanifest"><link rel="mask-icon" href="static/images/safari-pinned-tab.svg" color="#5bbad5"><link rel="shortcut icon" href="static/images/favicon.ico"><meta name="msapplication-TileColor" content="#da532c"><meta name="msapplication-config" content="static/images/browserconfig.xml"><meta name="theme-color" content="#ffffff"><meta name="keywords" content="lego,static site generator,nodejs"><meta name="author" content="Sivasubramanyam A"><meta name="viewport" content="width=device-width,initial-scale=1"><link href="static/css/styles-e2fbcc6720.css" rel="stylesheet"><link href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,700" rel="stylesheet"></head><body><div class="navbar">LEGO</div><main role="main"><div class="container"><h2 class="text-center">Lego is an opinionated static site generator built with NodeJS.</h2><div class="section"><div>Having written several build tools at work over the last few years, I wanted to try my hands at rolling out a full featured static site generator. This is turning out to be a great learning experience and I hope to blog about this soon.</div></div><div class="section"><h3>Features</h3><ul><li>Uses Liquid as the templating engine.</li><li>Supports Markdown files with YAML front-matter.</li><li>Minifies and uglifies JS and CSS files with a specified <span><pre>.browserlist.rc</pre></span>.</li><li>Does asset revision of CSS and JS files.</li><li>Minifies output HTML.</li><li>Live-reload during development.</li><li>Supports including html in md by implementing a custom md syntax. For example, to include a table, <span><pre>::: include table.html :::</pre></span></li><li>JPG and PNG images under <span><pre>static</pre></span> will be optimised with <span><pre>imageoptim</pre></span>.</li><li>Generates images for various resolutions and automatically inserts <span><pre>picture</pre></span>elements with the corresponding <span><pre>source</pre></span>elements.</li><li>Copies CNAME to build directory, so will work with GH Pages with a custom domain.</li><li>🚧 LESS and Sass support.</li><li>🚧 Extracting and inlining critical CSS.</li><li>🚧 Generating sitemaps.</li></ul></div><div class="section"><h3>Installation</h3><div>Run <span><pre>npm i -g @astronomersiva/lego</pre></span>.</div></div><div class="section"><h3>Usage</h3><ul><li>To create a new project, run <span><pre>lego g siteName</pre></span>.</li><li>To start the development server, run <span><pre>lego s</pre></span>.</li><li>To create an optimised build for deployment, run <span><pre>lego</pre></span>.</li><li>To include an HTML in a markdown file, use <span><pre>::: include table.html :::</pre></span>.</li><li>To automatically generate images for various resolutions,<br><code>::: lego-image src="/static/images/${IMAGE}" res="1080,500,320" alt="alternate text" class="img-responsive center-block" :::</code>.</li><li>lego also exposes a <span><pre>isDevelopment</pre></span>variable that you can use to disable certain stuff in development. For example, analytics. For example,<br><code>&#123;% unless isDevelopment %} &lt;!-- analytics code --&gt; &#123;% endunless %}</code></li></ul></div><div class="section"><h3>Directory Structure</h3><pre>
.
├── CNAME
├── build // contains the built site
Expand Down
2 changes: 1 addition & 1 deletion lib/lego.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = async function(args) {
watch(site, runTask);
} else {
const site = new Site();
await runTask([...build, 'revisionAssets'], site);
await runTask([...build, ['revisionAssets', 'optimiseImages']], site);

site.logger.success(`Build created at ${chalk.cyan(BUILD)}.`);
}
Expand Down
41 changes: 41 additions & 0 deletions lib/tasks/optimiseImages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module.exports = async function(site) {
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
const glob = require('glob');
const path = require('path');

const { BUILD, STATIC, IMAGES } = require('../utils/constants');

try {
let message = 'Optimising images';
site.logger.await(message);

// this monstrosity is because imagemin does not support
// overwriting the images when a glob is provided.
// PRs and issues related to this are closed without any
// clear path forward
let images = glob.sync(`${STATIC}/**/*.+(${IMAGES.join('|')})`);

// skipping favicons
images = images.filter(image => !image.includes('favicon'));

let imageOptimPromises = [];
for (let index = 0; index < images.length; index++) {
let image = images[index];
imageOptimPromises.push(
imagemin([image], path.dirname(image.replace(STATIC, `${BUILD}/${STATIC}`)), {
plugins: [
imageminMozjpeg(),
imageminPngquant({quality: '65-80'})
]
})
);
}

await Promise.all(imageOptimPromises);
site.logger.success(message);
} catch (error) {
throw error;
}
}
12 changes: 9 additions & 3 deletions lib/utils/constants.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
const IMAGES = [
'webp',
'png',
'jpg',
'jpeg'
];

module.exports = {
BUILD: 'build',
PAGES: 'pages',
POSTS: 'posts',
STATIC: 'static',
LAYOUTS: 'layouts',
DATA: 'data',
IMAGES,
MEDIA: [
'webp',
'png',
'jpg',
...IMAGES,
'gif',
'mp4'
]
Expand Down
Loading

0 comments on commit dff8b18

Please sign in to comment.