From 7cf6a3ba6ba9764d4881fee30632c305c9be7724 Mon Sep 17 00:00:00 2001 From: gr <13141462+gonzarodriguezt@users.noreply.github.com> Date: Sat, 26 Oct 2019 23:29:06 -0300 Subject: [PATCH] Parcel 2: HTMLNano Optimizer (#3673) --- packages/configs/default/index.json | 3 +- packages/configs/default/package.json | 1 + packages/core/integration-tests/test/html.js | 20 +++++----- packages/optimizers/htmlnano/package.json | 20 ++++++++++ .../htmlnano/src/HTMLNanoOptimizer.js | 38 +++++++++++++++++++ 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 packages/optimizers/htmlnano/package.json create mode 100644 packages/optimizers/htmlnano/src/HTMLNanoOptimizer.js diff --git a/packages/configs/default/index.json b/packages/configs/default/index.json index ad6ca10a878..92c3e54dad5 100644 --- a/packages/configs/default/index.json +++ b/packages/configs/default/index.json @@ -29,7 +29,8 @@ }, "optimizers": { "*.css": ["@parcel/optimizer-cssnano"], - "*.js": ["@parcel/optimizer-terser"] + "*.js": ["@parcel/optimizer-terser"], + "*.html": ["@parcel/optimizer-htmlnano"] }, "packagers": { "*.html": "@parcel/packager-html", diff --git a/packages/configs/default/package.json b/packages/configs/default/package.json index e0b9fe659e0..7b28311b439 100644 --- a/packages/configs/default/package.json +++ b/packages/configs/default/package.json @@ -14,6 +14,7 @@ "@parcel/namer-default": "^2.0.0-alpha.2.1", "@parcel/optimizer-cssnano": "^2.0.0-alpha.2.1", "@parcel/optimizer-terser": "^2.0.0-alpha.2.1", + "@parcel/optimizer-htmlnano": "^2.0.0-alpha.2.1", "@parcel/packager-css": "^2.0.0-alpha.2.1", "@parcel/packager-html": "^2.0.0-alpha.2.1", "@parcel/packager-js": "^2.0.0-alpha.2.1", diff --git a/packages/core/integration-tests/test/html.js b/packages/core/integration-tests/test/html.js index 27a6633daf8..78f10855af6 100644 --- a/packages/core/integration-tests/test/html.js +++ b/packages/core/integration-tests/test/html.js @@ -199,15 +199,15 @@ describe('html', function() { ); }); - it.skip('should minify HTML in production mode', async function() { + it('should minify HTML in production mode', async function() { let inputFile = path.join(__dirname, '/integration/htmlnano/index.html'); await bundle(inputFile, { - production: true + minify: true }); let inputSize = (await inputFS.stat(inputFile)).size; - let outputFile = path.join(__dirname, '/dist/index.html'); + let outputFile = path.join(distDir, 'index.html'); let outputSize = (await outputFS.stat(outputFile)).size; assert(inputSize > outputSize); @@ -227,16 +227,16 @@ describe('html', function() { assert.equal(html.length, 0); }); - it.skip('should read .htmlnanorc and minify HTML in production mode', async function() { + it('should read .htmlnanorc and minify HTML in production mode', async function() { await bundle( path.join(__dirname, '/integration/htmlnano-config/index.html'), { - production: true + minify: true } ); let html = await outputFS.readFile( - path.join(__dirname, '/dist/index.html'), + path.join(distDir, 'index.html'), 'utf8' ); @@ -255,23 +255,23 @@ describe('html', function() { // minifySvg is false assert( html.includes( - 'SVG' + 'SVG' ) ); }); - it.skip('should not minify default values inside HTML in production mode', async function() { + it('should not minify default values inside HTML in production mode', async function() { let inputFile = path.join( __dirname, '/integration/htmlnano-defaults-form/index.html' ); await bundle(inputFile, { - production: true + minify: true }); let inputSize = (await inputFS.stat(inputFile)).size; - let outputFile = path.join(__dirname, '/dist/index.html'); + let outputFile = path.join(distDir, '/index.html'); let outputSize = (await outputFS.stat(outputFile)).size; assert(inputSize > outputSize); diff --git a/packages/optimizers/htmlnano/package.json b/packages/optimizers/htmlnano/package.json new file mode 100644 index 00000000000..fbac5bc2a6d --- /dev/null +++ b/packages/optimizers/htmlnano/package.json @@ -0,0 +1,20 @@ +{ + "name": "@parcel/optimizer-htmlnano", + "version": "2.0.0-alpha.2.1", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/parcel-bundler/parcel.git" + }, + "main": "src/HTMLNanoOptimizer.js", + "engines": { + "parcel": "^2.0.0-alpha.1.1" + }, + "dependencies": { + "@parcel/plugin": "^2.0.0-alpha.2.1", + "@parcel/utils": "^2.0.0-alpha.2", + "htmlnano": "^0.2.2", + "nullthrows": "^1.1.1", + "posthtml": "^0.11.3" + } +} diff --git a/packages/optimizers/htmlnano/src/HTMLNanoOptimizer.js b/packages/optimizers/htmlnano/src/HTMLNanoOptimizer.js new file mode 100644 index 00000000000..31445b83c2a --- /dev/null +++ b/packages/optimizers/htmlnano/src/HTMLNanoOptimizer.js @@ -0,0 +1,38 @@ +// @flow strict-local + +// $FlowFixMe this is untyped +import htmlnano from 'htmlnano'; +import {loadConfig} from '@parcel/utils'; +import {Optimizer} from '@parcel/plugin'; +import posthtml from 'posthtml'; +import path from 'path'; + +export default new Optimizer({ + async optimize({contents, map, options}) { + if (!options.minify) { + return {contents, map}; + } + + if (typeof contents !== 'string') { + throw new Error( + 'HTMLNanoOptimizer: Only string contents are currently supported' + ); + } + + let userConfig = await loadConfig( + options.inputFS, + path.join(options.rootDir, 'index.html'), + ['.htmlnanorc', '.htmlnanorc.js'] + ); + + const htmlNanoConfig = { + minifyJs: false, + ...userConfig?.config + }; + + return { + contents: (await posthtml([htmlnano(htmlNanoConfig)]).process(contents)) + .html + }; + } +});