├── .gitattributes ├── .gitignore ├── AUTHORS ├── test ├── expected │ └── test.html ├── fixtures │ └── test.html └── test.js ├── CONTRIBUTING.md ├── docs ├── htmlmin-options.md ├── htmlmin-overview.md └── htmlmin-examples.md ├── .editorconfig ├── .jshintrc ├── package.json ├── .github └── workflows │ └── test.yml ├── tasks └── htmlmin.js ├── LICENSE-MIT ├── Gruntfile.js ├── CHANGELOG └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | tmp 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Sindre Sorhus (https://github.com/sindresorhus) 2 | -------------------------------------------------------------------------------- /test/expected/test.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /test/fixtures/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please see the [Contributing to grunt](https://gruntjs.com/contributing) guide for information on contributing to this project. 2 | -------------------------------------------------------------------------------- /docs/htmlmin-options.md: -------------------------------------------------------------------------------- 1 | # Options 2 | 3 | See the `html-minifier` [options](https://github.com/kangax/html-minifier#options-quick-reference). 4 | -------------------------------------------------------------------------------- /docs/htmlmin-overview.md: -------------------------------------------------------------------------------- 1 | *Issues with the output should be reported on the `htmlmin` [issue tracker](https://github.com/kangax/html-minifier/issues/new).* 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "eqnull": true, 6 | "immed": true, 7 | "latedef": true, 8 | "newcap": true, 9 | "noarg": true, 10 | "node": true, 11 | "sub": true, 12 | "undef": true, 13 | "unused": true 14 | } 15 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var grunt = require('grunt'); 3 | 4 | exports.htmlmin = { 5 | compile: function (test) { 6 | test.expect(1); 7 | 8 | var actual = grunt.file.read('tmp/test.html'); 9 | var expected = grunt.file.read('test/expected/test.html'); 10 | test.equal(actual, expected, 'should minify HTML'); 11 | 12 | test.done(); 13 | }, 14 | empty: function (test) { 15 | test.expect(1); 16 | 17 | test.ok(!grunt.file.exists('tmp/idontexist.html'), 'Empty minified file should not exist'); 18 | 19 | test.done(); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-contrib-htmlmin", 3 | "description": "Minify HTML", 4 | "version": "3.1.0", 5 | "author": { 6 | "name": "Grunt Team", 7 | "url": "https://gruntjs.com/" 8 | }, 9 | "repository": "gruntjs/grunt-contrib-htmlmin", 10 | "license": "MIT", 11 | "engines": { 12 | "node": ">=12" 13 | }, 14 | "main": "tasks/htmlmin.js", 15 | "scripts": { 16 | "test": "grunt test" 17 | }, 18 | "dependencies": { 19 | "chalk": "^2.4.2", 20 | "html-minifier": "^4.0.0", 21 | "pretty-bytes": "^5.1.0" 22 | }, 23 | "devDependencies": { 24 | "grunt": "^1.5.3", 25 | "grunt-contrib-clean": "^2.0.1", 26 | "grunt-contrib-internal": "^7.0.0", 27 | "grunt-contrib-jshint": "^3.2.0", 28 | "grunt-contrib-nodeunit": "^4.0.0" 29 | }, 30 | "keywords": [ 31 | "gruntplugin", 32 | "html", 33 | "min", 34 | "minify", 35 | "compress", 36 | "optimize" 37 | ], 38 | "files": [ 39 | "tasks" 40 | ], 41 | "appveyor_id": "sn73i2qggqeolnc2" 42 | } 43 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | env: 6 | FORCE_COLOR: 2 7 | 8 | jobs: 9 | run: 10 | name: Node ${{ matrix.node }} on ${{ matrix.os }} 11 | runs-on: ${{ matrix.os }} 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | node: [12, 14, 16] 17 | os: [ubuntu-latest, windows-latest] 18 | 19 | steps: 20 | - name: Clone repository 21 | uses: actions/checkout@v2 22 | 23 | - name: Set up Node.js 24 | uses: actions/setup-node@v2 25 | with: 26 | node-version: ${{ matrix.node }} 27 | 28 | - name: Install npm dependencies 29 | run: npm ci 30 | 31 | - name: Run tests 32 | run: npm test 33 | 34 | # We test multiple Windows shells because of prior stdout buffering issues 35 | # filed against Grunt. https://github.com/joyent/node/issues/3584 36 | - name: Run PowerShell tests 37 | run: "npm test # PowerShell" # Pass comment to PS for easier debugging 38 | shell: powershell 39 | if: startsWith(matrix.os, 'windows') 40 | -------------------------------------------------------------------------------- /tasks/htmlmin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var chalk = require('chalk'); 3 | var prettyBytes = require('pretty-bytes'); 4 | var minify = require('html-minifier').minify; 5 | 6 | module.exports = function (grunt) { 7 | grunt.registerMultiTask('htmlmin', 'Minify HTML', function () { 8 | var options = this.options(); 9 | var count = 0; 10 | 11 | this.files.forEach(function (file) { 12 | var min; 13 | var src = file.src[0]; 14 | 15 | if (!src) { 16 | return; 17 | } 18 | 19 | var max = grunt.file.read(src); 20 | 21 | try { 22 | min = minify(max, options); 23 | } catch (err) { 24 | grunt.warn(src + '\n' + err); 25 | return; 26 | } 27 | 28 | count++; 29 | 30 | grunt.file.write(file.dest, min); 31 | grunt.verbose.writeln('Minified ' + chalk.cyan(file.dest) + ' ' + prettyBytes(max.length) + ' → ' + prettyBytes(min.length)); 32 | }); 33 | 34 | grunt.log.writeln('Minified ' + chalk.cyan(count) + ' files' + (this.files.length !== count ? ' (' + chalk.red(this.files.length - count) + ' failed)' : '')); 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Sindre Sorhus, contributors 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function (grunt) { 3 | grunt.initConfig({ 4 | jshint: { 5 | options: { 6 | jshintrc: '.jshintrc' 7 | }, 8 | all: [ 9 | 'Gruntfile.js', 10 | 'tasks/*.js', 11 | '<%= nodeunit.tests %>' 12 | ] 13 | }, 14 | clean: { 15 | test: ['tmp'] 16 | }, 17 | htmlmin: { 18 | options: { 19 | removeComments: true, 20 | collapseWhitespace: true 21 | }, 22 | compile: { 23 | files: { 24 | 'tmp/test.html': 'test/fixtures/test.html' 25 | } 26 | }, 27 | empty: { 28 | files: { 29 | 'tmp/idontexist.html': 'test/fixtures/idontexist.html' 30 | } 31 | } 32 | }, 33 | nodeunit: { 34 | tests: ['test/test.js'] 35 | } 36 | }); 37 | 38 | grunt.loadTasks('tasks'); 39 | grunt.loadNpmTasks('grunt-contrib-clean'); 40 | grunt.loadNpmTasks('grunt-contrib-jshint'); 41 | grunt.loadNpmTasks('grunt-contrib-nodeunit'); 42 | grunt.loadNpmTasks('grunt-contrib-internal'); 43 | 44 | grunt.registerTask('test', ['jshint', 'clean', 'htmlmin', 'nodeunit']); 45 | grunt.registerTask('default', ['test', 'build-contrib']); 46 | }; 47 | -------------------------------------------------------------------------------- /docs/htmlmin-examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | ## Simple Example 4 | 5 | ```js 6 | grunt.initConfig({ 7 | htmlmin: { // Task 8 | dist: { // Target 9 | options: { // Target options 10 | removeComments: true, 11 | collapseWhitespace: true 12 | }, 13 | files: { // Dictionary of files 14 | 'dist/index.html': 'src/index.html', // 'destination': 'source' 15 | 'dist/contact.html': 'src/contact.html' 16 | } 17 | }, 18 | dev: { // Another target 19 | files: { 20 | 'dist/index.html': 'src/index.html', 21 | 'dist/contact.html': 'src/contact.html' 22 | } 23 | } 24 | } 25 | }); 26 | 27 | grunt.registerTask('default', ['htmlmin']); 28 | ``` 29 | 30 | ## Example with Nested Files 31 | 32 | ```js 33 | grunt.initConfig({ 34 | htmlmin: { // Task 35 | dist: { // Target 36 | options: { // Target options 37 | removeComments: true, 38 | collapseWhitespace: true 39 | }, 40 | files: { // Dictionary of files 41 | 'dist/index.html': 'src/index.html', // 'destination': 'source' 42 | 'dist/contact.html': 'src/contact.html' 43 | } 44 | }, 45 | dev: { // Another target 46 | files: [{ 47 | expand: true, 48 | cwd: 'app', 49 | src: ['src/**/*.html', '*.html'], 50 | dest: 'dist' 51 | }] 52 | } 53 | } 54 | }); 55 | 56 | grunt.registerTask('default', ['htmlmin']); 57 | ``` 58 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | v3.1.0: 2 | date: 2019-04-01 3 | changes: 4 | - Updated html-minifier to v4.0.0. 5 | - Updated all other dependencies. 6 | v3.0.0: 7 | date: 2018-08-26 8 | changes: 9 | - Updated all dependencies. 10 | - Requires Node.js >= 6. 11 | v2.4.0: 12 | date: 2017-05-16 13 | changes: 14 | - Updated html-minifier to v3.5.0. 15 | v2.3.0: 16 | date: 2017-03-08 17 | changes: 18 | - Updated html-minifier to v3.4.0. 19 | v2.2.0: 20 | date: 2017-01-30 21 | changes: 22 | - Updated html-minifier to v3.3.0. 23 | v2.1.0: 24 | date: 2017-01-14 25 | changes: 26 | - Updated html-minifier to v3.2.3 and pretty-bytes to 4.0.2. 27 | v2.0.0: 28 | date: 2016-07-19 29 | changes: 30 | - Updated html-minifier to v3.0.1. Note that Node.js < 4 isn't supported anymore. 31 | v1.5.0: 32 | date: 2016-07-13 33 | changes: 34 | - Updated html-minifier to v2.1.7. 35 | v1.4.0: 36 | date: 2016-04-19 37 | changes: 38 | - Updated html-minifier to v2.0.0. 39 | v1.3.0: 40 | date: 2016-04-10 41 | changes: 42 | - Updated html-minifier to v1.5.0. 43 | v1.2.0: 44 | date: 2016-03-31 45 | changes: 46 | - Updated html-minifier to v1.4.0. 47 | v1.1.0: 48 | date: 2016-03-18 49 | changes: 50 | - Updated html-minifier to v1.3.0. 51 | v1.0.0: 52 | date: 2016-03-04 53 | changes: 54 | - Updated html-minifier to v1.2.0. 55 | - Point main to task. 56 | - Drop peerDeps. 57 | v0.6.0: 58 | date: 2015-10-28 59 | changes: 60 | - Updated html-minifier to v1.0.0. 61 | v0.5.0: 62 | date: 2015-09-25 63 | changes: 64 | - Updated html-minifier to v0.8.0. 65 | v0.4.0: 66 | date: 2015-02-06 67 | changes: 68 | - Updated html-minifier to v0.7.0. 69 | v0.3.0: 70 | date: 2014-05-05 71 | changes: 72 | - Drop Node.js 0.8 support. 73 | - Updated html-minifier to v0.6.0. 74 | v0.2.0: 75 | date: 2014-02-09 76 | changes: 77 | - Rewrite task. Drop concat support. 78 | v0.1.3: 79 | date: 2013-04-06 80 | changes: 81 | - Fail target when minify encounters an error. 82 | v0.1.2: 83 | date: 2013-04-05 84 | changes: 85 | - Update html-minifier which fixes IE conditional comments and prefixed HTML elements `