Skip to content
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.

Commit

Permalink
feat: html-minifier integration
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyaSemenov committed May 10, 2019
1 parent 9f6c46c commit cb95cc3
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 9 deletions.
16 changes: 13 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const basePlugin = require('./plugins/base')
const logger = require('./logger')
const serveStatic = require('./utils/serveStatic')
const renderHtml = require('./utils/renderHtml')
const minifyHtml = require('./utils/minifyHtml')
const emoji = require('./emoji')
const inspect = require('./utils/inspect')
const validateConfig = require('./validateConfig')
Expand Down Expand Up @@ -76,7 +77,8 @@ class Ream extends Event {
extract: !this.options.dev
},
pwa: false,
minimize: !this.options.dev
minimize: !this.options.dev,
minifyHtml: false
}

// config from constructor can override user config
Expand Down Expand Up @@ -209,7 +211,7 @@ class Ream extends Event {
routes.map(async route => {
// Fake req
const context = { req: { url: route } }
const html = await renderHtml(this.renderer, context)
const html = await this.renderHtml(context)
const targetPath = this.resolveOutDir(
`generated/${route.replace(/\/?$/, '/index.html')}`
)
Expand Down Expand Up @@ -335,7 +337,7 @@ class Ream extends Event {
}

const context = { req, res }
const html = await renderHtml(this.renderer, context)
const html = await this.renderHtml(context)

res.setHeader('content-type', 'text/html')
res.end(html)
Expand Down Expand Up @@ -403,6 +405,14 @@ class Ream extends Event {
this.emit('renderer-ready', serverType)
}

async renderHtml(context) {
let html = await renderHtml(this.renderer, context)
if (this.config.minifyHtml) {
html = minifyHtml(html, this.config.minifyHtml)
}
return html
}

resolveOutDir(...args) {
return this.resolveBaseDir(this.config.outDir, ...args)
}
Expand Down
13 changes: 13 additions & 0 deletions lib/utils/minifyHtml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { minify } = require('html-minifier')

const defaultOptions = {
collapseWhitespace: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyCSS: true
}

module.exports = (html, options) =>
minify(html, options === true ? defaultOptions : options)
3 changes: 2 additions & 1 deletion lib/validateConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const schema = joi.object().keys({
// To add more controls, e.g. "notifyOnUpdate" will show a notifier when a new update is available
pwa: joi.boolean(),
minimize: joi.boolean(),
defaultBabelPreset: joi.any().valid(['minimal', false])
defaultBabelPreset: joi.any().valid(['minimal', false]),
minifyHtml: joi.alternatives().try(joi.object(), joi.boolean())
})

module.exports = config => {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"file-loader": "^1.1.6",
"fs-extra": "^6.0.0",
"hash-sum": "^1.0.2",
"html-minifier": "^4.0.0",
"internal-ip": "^3.0.1",
"joi": "^13.6.0",
"joycon": "^1.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/projects/html-minifier/index.test.js TAP test/projects/html-minifier > page 1`] = `
<!DOCTYPE html><html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui" />
<title data-ream-head="true"></title>
<link rel="preload" href="/_ream/chunk-vendors.js" as="script"><link rel="preload" href="/_ream/client.js" as="script"><link rel="prefetch" href="/_ream/chunk--base-pages-index.js"><style data-vue-ssr-id="234417f0:0">
.test {
color: black
}
</style>
</head>
<body>
<div id="_ream" data-server-rendered="true"><div class="test">
Test
</div></div>
<script>window.__REAM__={"initialData":{}}</script><script src="/_ream/chunk-vendors.js" defer></script><script src="/_ream/client.js" defer></script>
</body>
</html>
`

exports[`test/projects/html-minifier/index.test.js TAP test/projects/html-minifier > page 2`] = `
<!doctype html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui"><title data-ream-head="true"></title><link rel="preload" href="/_ream/chunk-vendors.js" as="script"><link rel="preload" href="/_ream/client.js" as="script"><link rel="prefetch" href="/_ream/chunk--base-pages-index.js"><style data-vue-ssr-id="234417f0:0">.test{color:#000}</style></head><body><div id="_ream" data-server-rendered="true"><div class="test">Test</div></div><script>window.__REAM__={"initialData":{}}</script><script src="/_ream/chunk-vendors.js" defer="defer"></script><script src="/_ream/client.js" defer="defer"></script></body></html>
`

exports[`test/projects/html-minifier/index.test.js TAP test/projects/html-minifier > page 3`] = `
<!DOCTYPE html><html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">
<title data-ream-head="true"></title>
<link rel="preload" href="/_ream/chunk-vendors.js" as="script"><link rel="preload" href="/_ream/client.js" as="script"><link rel="prefetch" href="/_ream/chunk--base-pages-index.js"><style data-vue-ssr-id="234417f0:0">.test{color:#000}</style>
</head>
<body>
<div id="_ream" data-server-rendered="true"><div class="test">
Test
</div></div>
<script>window.__REAM__={"initialData":{}}</script><script src="/_ream/chunk-vendors.js" defer="defer"></script><script src="/_ream/client.js" defer="defer"></script>
</body>
</html>
`
5 changes: 3 additions & 2 deletions test/lib/testProject.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Client {
}
}

module.exports = function(baseDir, fn) {
module.exports = function(baseDir, fn, config) {
// Calculate relative base directory for consistent snapshots.
const relativeBaseDir = path.relative('.', baseDir)
return tap.test(relativeBaseDir, async t => {
Expand All @@ -49,7 +49,8 @@ module.exports = function(baseDir, fn) {
css: {
extract: false
},
minimize: false
minimize: false,
...config
}
)
app.chainWebpack(config => {
Expand Down
25 changes: 25 additions & 0 deletions test/projects/html-minifier/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const testProject = require('../../lib/testProject')

const configs = [
{
minifyHtml: false
},
{
minifyHtml: true
},
{
minifyHtml: {
minifyCSS: true
}
}
]

for (const config of configs) {
testProject(
__dirname,
async (t, c) => {
t.matchSnapshot((await c.axios.get('/')).data, 'page')
},
config
)
}
11 changes: 11 additions & 0 deletions test/projects/html-minifier/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<div class="test">
Test
</div>
</template>

<style>
.test {
color: black
}
</style>
3 changes: 3 additions & 0 deletions test/projects/html-minifier/ream.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
fsRoutes: true
}
68 changes: 65 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,14 @@ callsites@^2.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=

camel-case@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
dependencies:
no-case "^2.2.0"
upper-case "^1.1.1"

camelcase-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
Expand Down Expand Up @@ -2575,6 +2583,13 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"

clean-css@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==
dependencies:
source-map "~0.6.0"

clean-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7"
Expand Down Expand Up @@ -2793,7 +2808,7 @@ commander@^2.14.1, commander@^2.9.0, commander@~2.17.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==

commander@~2.20.0:
commander@^2.19.0, commander@~2.20.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
Expand Down Expand Up @@ -5416,6 +5431,11 @@ he@^1.1.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=

he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==

hex-color-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
Expand Down Expand Up @@ -5483,6 +5503,19 @@ html-entities@^1.2.0:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=

html-minifier@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-4.0.0.tgz#cca9aad8bce1175e02e17a8c33e46d8988889f56"
integrity sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==
dependencies:
camel-case "^3.0.0"
clean-css "^4.2.1"
commander "^2.19.0"
he "^1.2.0"
param-case "^2.1.1"
relateurl "^0.2.7"
uglify-js "^3.5.1"

http-cache-semantics@^3.8.1:
version "3.8.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
Expand Down Expand Up @@ -7139,6 +7172,11 @@ loud-rejection@^1.0.0, loud-rejection@^1.6.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"

lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=

lowercase-keys@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
Expand Down Expand Up @@ -7689,6 +7727,13 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4"
integrity sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==

no-case@^2.2.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
dependencies:
lower-case "^1.1.1"

node-emoji@^1.4.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.8.1.tgz#6eec6bfb07421e2148c75c6bba72421f8530a826"
Expand Down Expand Up @@ -8520,6 +8565,13 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"

param-case@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
dependencies:
no-case "^2.2.0"

parse-asn1@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
Expand Down Expand Up @@ -9779,6 +9831,11 @@ regjsparser@^0.3.0:
dependencies:
jsesc "~0.5.0"

relateurl@^0.2.7:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=

release-zalgo@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730"
Expand Down Expand Up @@ -10484,7 +10541,7 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, sour
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=

source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
Expand Down Expand Up @@ -11359,7 +11416,7 @@ uglify-js@^2.6:
optionalDependencies:
uglify-to-browserify "~1.0.0"

uglify-js@^3.1.4:
uglify-js@^3.1.4, uglify-js@^3.5.1:
version "3.5.11"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.11.tgz#833442c0aa29b3a7d34344c7c63adaa3f3504f6a"
integrity sha512-izPJg8RsSyqxbdnqX36ExpbH3K7tDBsAU/VfNv89VkMFy3z39zFjunQGsSHOlGlyIfGLGprGeosgQno3bo2/Kg==
Expand Down Expand Up @@ -11569,6 +11626,11 @@ update-notifier@^2.3.0, update-notifier@^2.5.0:
semver-diff "^2.0.0"
xdg-basedir "^3.0.0"

upper-case@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=

uri-js@^4.2.1:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
Expand Down

0 comments on commit cb95cc3

Please sign in to comment.