From 8f2b5a9fd0618bb322dbc971d2ee32918fff4185 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 8 Sep 2019 07:37:00 +0300 Subject: [PATCH 1/3] feat: minify HTML on build --- build.js | 3 ++ package-lock.json | 108 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + 3 files changed, 107 insertions(+), 5 deletions(-) diff --git a/build.js b/build.js index 6877cd2dc35e4..a38962ec682e7 100755 --- a/build.js +++ b/build.js @@ -16,6 +16,7 @@ const markdown = require('metalsmith-markdown') const prism = require('metalsmith-prism') const permalinks = require('metalsmith-permalinks') const pagination = require('metalsmith-yearly-pagination') +const htmlMinifier = require('metalsmith-html-minifier') const defaultsDeep = require('lodash.defaultsdeep') const autoprefixer = require('autoprefixer') const marked = require('marked') @@ -179,6 +180,8 @@ function buildLocale (source, locale, opts) { pattern: /\.js$/ })) .use(layouts()) + // Use the default options + .use(htmlMinifier()) // Pipes the generated files into their respective subdirectory in the build // directory. .destination(path.join(__dirname, 'build', locale)) diff --git a/package-lock.json b/package-lock.json index 94fb48cbc35ba..c0d037cffb3a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -253,8 +253,7 @@ "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { "version": "12.7.12", @@ -812,6 +811,15 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -972,6 +980,14 @@ } } }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "requires": { + "source-map": "~0.6.0" + } + }, "cli-boxes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", @@ -3082,6 +3098,20 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" }, + "html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "requires": { + "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" + } + }, "html-tags": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", @@ -4142,6 +4172,11 @@ "signal-exit": "^3.0.0" } }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -4374,6 +4409,45 @@ "rss": "^1.2.2" } }, + "metalsmith-html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/metalsmith-html-minifier/-/metalsmith-html-minifier-4.0.0.tgz", + "integrity": "sha512-SRVK/j4nmeEP6eY18hx0htCjeNYrMzsVbH6agUBdG0bWbuivpJiZLOOeDmE7ktoPDvSn/M/6OMNXSEzplMPFxg==", + "requires": { + "html-minifier": "^4.0.0", + "lodash.defaultsdeep": "^4.6.1", + "multimatch": "^4.0.0" + }, + "dependencies": { + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + }, + "multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + } + } + } + }, "metalsmith-layouts": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/metalsmith-layouts/-/metalsmith-layouts-2.3.1.tgz", @@ -4697,6 +4771,14 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, "nock": { "version": "11.7.0", "resolved": "https://registry.npmjs.org/nock/-/nock-11.7.0.tgz", @@ -5106,6 +5188,14 @@ "semver": "^6.2.0" } }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "^2.2.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5753,6 +5843,11 @@ "rc": "^1.2.8" } }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, "remark": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", @@ -8029,7 +8124,6 @@ "version": "3.6.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz", "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==", - "optional": true, "requires": { "commander": "~2.20.3", "source-map": "~0.6.1" @@ -8038,8 +8132,7 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "optional": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" } } }, @@ -8363,6 +8456,11 @@ "xdg-basedir": "^3.0.0" } }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", diff --git a/package.json b/package.json index cb86b8170228c..62e2176924eff 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "metalsmith-discover-helpers": "^0.1.1", "metalsmith-discover-partials": "^0.1.2", "metalsmith-feed": "^1.0.0", + "metalsmith-html-minifier": "^4.0.0", "metalsmith-layouts": "^2.3.1", "metalsmith-markdown": "^1.3.0", "metalsmith-metadata": "0.0.4", From abdd6de607885e003dbac1c98b958e51513b0b5a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Sun, 8 Sep 2019 10:18:49 +0300 Subject: [PATCH 2/3] Improve html-minifier's options. --- build.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/build.js b/build.js index a38962ec682e7..75da7f3349ed8 100755 --- a/build.js +++ b/build.js @@ -47,6 +47,33 @@ const markedOptions = { renderer } +const htmlMinifierOpts = { + collapseBooleanAttributes: true, + collapseWhitespace: true, + conservativeCollapse: true, // This is needed as things are now + decodeEntities: true, + minifyCSS: { + level: { + 1: { + specialComments: 0 + } + } + }, + minifyJS: false, // we don't have a lot inline JS and this slows down things + minifyURLs: false, + processConditionalComments: true, + removeAttributeQuotes: true, + removeComments: true, + removeOptionalAttributes: true, + removeOptionalTags: true, + removeRedundantAttributes: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + removeTagWhitespace: false, + sortAttributes: true, + sortClassName: true +} + // This function imports a given language file and uses the default language set // in DEFAULT_LANG as a fallback to prevent any strings that aren't filled out // from appearing as blank. @@ -181,7 +208,7 @@ function buildLocale (source, locale, opts) { })) .use(layouts()) // Use the default options - .use(htmlMinifier()) + .use(htmlMinifier({ minifierOptions: htmlMinifierOpts })) // Pipes the generated files into their respective subdirectory in the build // directory. .destination(path.join(__dirname, 'build', locale)) From 312f399dd7f427cfb3ebade93aac007563c5cecd Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 1 Oct 2019 11:31:40 +0300 Subject: [PATCH 3/3] Skip html-minifier on dev. --- build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.js b/build.js index 75da7f3349ed8..3ef7fbc1564d7 100755 --- a/build.js +++ b/build.js @@ -208,7 +208,7 @@ function buildLocale (source, locale, opts) { })) .use(layouts()) // Use the default options - .use(htmlMinifier({ minifierOptions: htmlMinifierOpts })) + .use(process.env.NODE_ENV !== 'development' ? htmlMinifier({ minifierOptions: htmlMinifierOpts }) : '') // Pipes the generated files into their respective subdirectory in the build // directory. .destination(path.join(__dirname, 'build', locale))