htmlnano 2.0.4 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.eslintignore +3 -2
  2. package/CHANGELOG.md +19 -0
  3. package/docs/docs/040-presets.md +4 -4
  4. package/docs/docs/050-modules.md +1 -1
  5. package/docs/docs/060-contribute.md +1 -1
  6. package/docs/docusaurus.config.js +5 -0
  7. package/docs/package-lock.json +563 -326
  8. package/docs/package.json +1 -0
  9. package/docs/versioned_docs/version-1.1.1/040-presets.md +4 -4
  10. package/docs/versioned_docs/version-1.1.1/050-modules.md +1 -2
  11. package/docs/versioned_docs/version-1.1.1/060-contribute.md +1 -1
  12. package/docs/versioned_docs/version-2.0.0/040-presets.md +4 -4
  13. package/docs/versioned_docs/version-2.0.0/050-modules.md +1 -1
  14. package/docs/versioned_docs/version-2.0.0/060-contribute.md +1 -1
  15. package/index.cjs +11 -0
  16. package/index.d.cts +3 -0
  17. package/index.d.mts +3 -0
  18. package/index.d.ts +3 -3
  19. package/index.mjs +2 -0
  20. package/lib/helpers.cjs +79 -0
  21. package/lib/helpers.mjs +53 -0
  22. package/lib/htmlnano.cjs +200 -0
  23. package/lib/htmlnano.mjs +196 -0
  24. package/lib/modules/{collapseAttributeWhitespace.js → collapseAttributeWhitespace.cjs} +2 -3
  25. package/lib/modules/collapseAttributeWhitespace.mjs +104 -0
  26. package/lib/modules/collapseBooleanAttributes.mjs +175 -0
  27. package/lib/modules/{collapseWhitespace.js → collapseWhitespace.cjs} +3 -2
  28. package/lib/modules/collapseWhitespace.mjs +132 -0
  29. package/lib/modules/custom.mjs +16 -0
  30. package/lib/modules/{deduplicateAttributeValues.js → deduplicateAttributeValues.cjs} +1 -1
  31. package/lib/modules/deduplicateAttributeValues.mjs +40 -0
  32. package/lib/modules/example.cjs +85 -0
  33. package/lib/modules/example.mjs +75 -0
  34. package/lib/modules/mergeScripts.mjs +56 -0
  35. package/lib/modules/{mergeStyles.js → mergeStyles.cjs} +1 -1
  36. package/lib/modules/mergeStyles.mjs +36 -0
  37. package/lib/modules/{minifyConditionalComments.js → minifyConditionalComments.cjs} +2 -2
  38. package/lib/modules/minifyConditionalComments.mjs +49 -0
  39. package/lib/modules/{minifyCss.js → minifyCss.cjs} +8 -8
  40. package/lib/modules/minifyCss.mjs +88 -0
  41. package/lib/modules/{minifyJs.js → minifyJs.cjs} +8 -9
  42. package/lib/modules/minifyJs.mjs +121 -0
  43. package/lib/modules/minifyJson.mjs +21 -0
  44. package/lib/modules/{minifySvg.js → minifySvg.cjs} +3 -4
  45. package/lib/modules/minifySvg.mjs +30 -0
  46. package/lib/modules/{minifyUrls.js → minifyUrls.cjs} +11 -12
  47. package/lib/modules/minifyUrls.mjs +229 -0
  48. package/lib/modules/normalizeAttributeValues.mjs +140 -0
  49. package/lib/modules/removeAttributeQuotes.mjs +12 -0
  50. package/lib/modules/{removeComments.js → removeComments.cjs} +1 -1
  51. package/lib/modules/removeComments.mjs +92 -0
  52. package/lib/modules/{removeEmptyAttributes.js → removeEmptyAttributes.cjs} +1 -1
  53. package/lib/modules/removeEmptyAttributes.mjs +121 -0
  54. package/lib/modules/{removeOptionalTags.js → removeOptionalTags.cjs} +1 -1
  55. package/lib/modules/removeOptionalTags.mjs +225 -0
  56. package/lib/modules/{removeRedundantAttributes.js → removeRedundantAttributes.cjs} +1 -2
  57. package/lib/modules/removeRedundantAttributes.mjs +141 -0
  58. package/lib/modules/{removeUnusedCss.js → removeUnusedCss.cjs} +12 -13
  59. package/lib/modules/removeUnusedCss.mjs +122 -0
  60. package/lib/modules/{sortAttributes.js → sortAttributes.cjs} +0 -1
  61. package/lib/modules/sortAttributes.mjs +121 -0
  62. package/lib/modules/{sortAttributesWithLists.js → sortAttributesWithLists.cjs} +1 -2
  63. package/lib/modules/sortAttributesWithLists.mjs +135 -0
  64. package/lib/presets/{ampSafe.js → ampSafe.cjs} +4 -9
  65. package/lib/presets/ampSafe.mjs +11 -0
  66. package/lib/presets/{max.js → max.cjs} +4 -9
  67. package/lib/presets/max.mjs +20 -0
  68. package/lib/presets/{safe.js → safe.cjs} +2 -3
  69. package/lib/presets/safe.mjs +65 -0
  70. package/package.json +40 -12
  71. package/index.js +0 -1
  72. package/lib/helpers.js +0 -53
  73. package/lib/htmlnano.js +0 -150
  74. /package/lib/modules/{collapseBooleanAttributes.js → collapseBooleanAttributes.cjs} +0 -0
  75. /package/lib/modules/{custom.js → custom.cjs} +0 -0
  76. /package/lib/modules/{mergeScripts.js → mergeScripts.cjs} +0 -0
  77. /package/lib/modules/{minifyJson.js → minifyJson.cjs} +0 -0
  78. /package/lib/modules/{normalizeAttributeValues.js → normalizeAttributeValues.cjs} +0 -0
  79. /package/lib/modules/{removeAttributeQuotes.js → removeAttributeQuotes.cjs} +0 -0
@@ -0,0 +1,122 @@
1
+ import { isStyleNode, extractCssFromStyleNode, optionalImport } from '../helpers.mjs';
2
+
3
+ // These options must be set and shouldn't be overriden to ensure uncss doesn't look at linked stylesheets.
4
+ const uncssOptions = {
5
+ ignoreSheets: [/\s*/],
6
+ stylesheets: [],
7
+ };
8
+
9
+ function processStyleNodeUnCSS(html, styleNode, uncssOptions, uncss) {
10
+ const css = extractCssFromStyleNode(styleNode);
11
+
12
+ return runUncss(html, css, uncssOptions, uncss).then(css => {
13
+ // uncss may have left some style tags empty
14
+ if (css.trim().length === 0) {
15
+ styleNode.tag = false;
16
+ styleNode.content = [];
17
+ return;
18
+ }
19
+ styleNode.content = [css];
20
+ });
21
+ }
22
+
23
+ function runUncss(html, css, userOptions, uncss) {
24
+ if (typeof userOptions !== 'object') {
25
+ userOptions = {};
26
+ }
27
+
28
+ const options = { ...userOptions, ...uncssOptions };
29
+ return new Promise((resolve, reject) => {
30
+ options.raw = css;
31
+ uncss(html, options, (error, output) => {
32
+ if (error) {
33
+ reject(error);
34
+ return;
35
+ }
36
+ resolve(output);
37
+ });
38
+ });
39
+ }
40
+
41
+ const purgeFromHtml = function (tree) {
42
+ // content is not used as we can directly used the parsed HTML,
43
+ // making the process faster
44
+ const selectors = [];
45
+
46
+ tree.walk(node => {
47
+ const classes = node.attrs && node.attrs.class && node.attrs.class.split(' ') || [];
48
+ const ids = node.attrs && node.attrs.id && node.attrs.id.split(' ') || [];
49
+ selectors.push(...classes, ...ids);
50
+ node.tag && selectors.push(node.tag);
51
+ return node;
52
+ });
53
+
54
+ return () => selectors;
55
+ };
56
+
57
+ function processStyleNodePurgeCSS(tree, styleNode, purgecssOptions, purgecss) {
58
+ const css = extractCssFromStyleNode(styleNode);
59
+ return runPurgecss(tree, css, purgecssOptions, purgecss)
60
+ .then(css => {
61
+ if (css.trim().length === 0) {
62
+ styleNode.tag = false;
63
+ styleNode.content = [];
64
+ return;
65
+ }
66
+ styleNode.content = [css];
67
+ });
68
+ }
69
+
70
+ function runPurgecss(tree, css, userOptions, purgecss) {
71
+ if (typeof userOptions !== 'object') {
72
+ userOptions = {};
73
+ }
74
+
75
+ const options = {
76
+ ...userOptions,
77
+ content: [{
78
+ raw: tree,
79
+ extension: 'html'
80
+ }],
81
+ css: [{
82
+ raw: css,
83
+ extension: 'css'
84
+ }],
85
+ extractors: [{
86
+ extractor: purgeFromHtml(tree),
87
+ extensions: ['html']
88
+ }]
89
+ };
90
+
91
+ return new purgecss.PurgeCSS()
92
+ .purge(options)
93
+ .then((result) => {
94
+ return result[0].css;
95
+ });
96
+ }
97
+
98
+ /** Remove unused CSS */
99
+ export default async function removeUnusedCss(tree, options, userOptions) {
100
+ const promises = [];
101
+ const html = userOptions.tool !== 'purgeCSS' && tree.render(tree);
102
+
103
+ const purgecss = await optionalImport('purgecss');
104
+ const uncss = await optionalImport('uncss');
105
+
106
+ tree.walk(node => {
107
+ if (isStyleNode(node)) {
108
+ if (userOptions.tool === 'purgeCSS') {
109
+ if (purgecss) {
110
+ promises.push(processStyleNodePurgeCSS(tree, node, userOptions, purgecss));
111
+ }
112
+ } else {
113
+ if (uncss) {
114
+ promises.push(processStyleNodeUnCSS(html, node, userOptions, uncss));
115
+ }
116
+ }
117
+ }
118
+ return node;
119
+ });
120
+
121
+ return Promise.all(promises).then(() => tree);
122
+ }
@@ -14,7 +14,6 @@ class AttributeTokenChain {
14
14
  constructor() {
15
15
  this.freqData = new Map(); // <attr, frequency>[]
16
16
  }
17
-
18
17
  addFromNodeAttrs(nodeAttrs) {
19
18
  Object.keys(nodeAttrs).forEach(attrName => {
20
19
  const attrNameLower = attrName.toLowerCase();
@@ -0,0 +1,121 @@
1
+ import { sort as timSort } from 'timsort';
2
+
3
+ const validOptions = new Set(['frequency', 'alphabetical']);
4
+
5
+ const processModuleOptions = options => {
6
+ if (options === true) return 'alphabetical';
7
+
8
+ return validOptions.has(options) ? options : false;
9
+ };
10
+
11
+ class AttributeTokenChain {
12
+ constructor() {
13
+ this.freqData = new Map(); // <attr, frequency>[]
14
+ }
15
+
16
+ addFromNodeAttrs(nodeAttrs) {
17
+ Object.keys(nodeAttrs).forEach(attrName => {
18
+ const attrNameLower = attrName.toLowerCase();
19
+
20
+ if (this.freqData.has(attrNameLower)) {
21
+ this.freqData.set(attrNameLower, this.freqData.get(attrNameLower) + 1);
22
+ } else {
23
+ this.freqData.set(attrNameLower, 1);
24
+ }
25
+ });
26
+ }
27
+
28
+ createSortOrder() {
29
+ let _sortOrder = [...this.freqData.entries()];
30
+ timSort(_sortOrder, (a, b) => b[1] - a[1]);
31
+
32
+ this.sortOrder = _sortOrder.map(i => i[0]);
33
+ }
34
+
35
+ sortFromNodeAttrs(nodeAttrs) {
36
+ const newAttrs = {};
37
+
38
+ // Convert node.attrs attrName into lower case.
39
+ const loweredNodeAttrs = {};
40
+ Object.entries(nodeAttrs).forEach(([attrName, attrValue]) => {
41
+ loweredNodeAttrs[attrName.toLowerCase()] = attrValue;
42
+ });
43
+
44
+ if (!this.sortOrder) {
45
+ this.createSortOrder();
46
+ }
47
+
48
+ this.sortOrder.forEach(attrNameLower => {
49
+ // The attrName inside "sortOrder" has been lowered
50
+ if (loweredNodeAttrs[attrNameLower] != null) {
51
+ newAttrs[attrNameLower] = loweredNodeAttrs[attrNameLower];
52
+ }
53
+ });
54
+
55
+ return newAttrs;
56
+ }
57
+ }
58
+
59
+ /** Sort attibutes */
60
+ export default function sortAttributes(tree, options, moduleOptions) {
61
+ const sortType = processModuleOptions(moduleOptions);
62
+
63
+ if (sortType === 'alphabetical') {
64
+ return sortAttributesInAlphabeticalOrder(tree);
65
+ }
66
+
67
+ if (sortType === 'frequency') {
68
+ return sortAttributesByFrequency(tree);
69
+ }
70
+
71
+ // Invalid configuration
72
+ return tree;
73
+ }
74
+
75
+ function sortAttributesInAlphabeticalOrder(tree) {
76
+ tree.walk(node => {
77
+ if (!node.attrs) {
78
+ return node;
79
+ }
80
+
81
+ const newAttrs = {};
82
+
83
+ Object.keys(node.attrs)
84
+ .sort((a, b) => typeof a.localeCompare === 'function' ? a.localeCompare(b) : a - b)
85
+ .forEach(attr => newAttrs[attr] = node.attrs[attr]);
86
+
87
+ node.attrs = newAttrs;
88
+
89
+ return node;
90
+ });
91
+
92
+ return tree;
93
+ }
94
+
95
+ function sortAttributesByFrequency(tree) {
96
+ const tokenchain = new AttributeTokenChain();
97
+
98
+ // Traverse through tree to get frequency
99
+ tree.walk(node => {
100
+ if (!node.attrs) {
101
+ return node;
102
+ }
103
+
104
+ tokenchain.addFromNodeAttrs(node.attrs);
105
+
106
+ return node;
107
+ });
108
+
109
+ // Traverse through tree again, this time sort the attributes
110
+ tree.walk(node => {
111
+ if (!node.attrs) {
112
+ return node;
113
+ }
114
+
115
+ node.attrs = tokenchain.sortFromNodeAttrs(node.attrs);
116
+
117
+ return node;
118
+ });
119
+
120
+ return tree;
121
+ }
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = collapseAttributeWhitespace;
7
7
  var _timsort = require("timsort");
8
- var _collapseAttributeWhitespace = require("./collapseAttributeWhitespace");
8
+ var _collapseAttributeWhitespace = require("./collapseAttributeWhitespace.cjs");
9
9
  // class, rel, ping
10
10
 
11
11
  const validOptions = new Set(['frequency', 'alphabetical']);
@@ -17,7 +17,6 @@ class AttributeTokenChain {
17
17
  constructor() {
18
18
  this.freqData = new Map(); // <attrValue, frequency>[]
19
19
  }
20
-
21
20
  addFromNodeAttrsArray(attrValuesArray) {
22
21
  attrValuesArray.forEach(attrValue => {
23
22
  if (this.freqData.has(attrValue)) {
@@ -0,0 +1,135 @@
1
+ // class, rel, ping
2
+ import { sort as timSort } from 'timsort';
3
+ import { attributesWithLists } from './collapseAttributeWhitespace.mjs';
4
+
5
+ const validOptions = new Set(['frequency', 'alphabetical']);
6
+ const processModuleOptions = options => {
7
+ if (options === true) return 'alphabetical';
8
+
9
+ return validOptions.has(options) ? options : false;
10
+ };
11
+
12
+ class AttributeTokenChain {
13
+ constructor() {
14
+ this.freqData = new Map(); // <attrValue, frequency>[]
15
+ }
16
+
17
+ addFromNodeAttrsArray(attrValuesArray) {
18
+ attrValuesArray.forEach(attrValue => {
19
+ if (this.freqData.has(attrValue)) {
20
+ this.freqData.set(attrValue, this.freqData.get(attrValue) + 1);
21
+ } else {
22
+ this.freqData.set(attrValue, 1);
23
+ }
24
+ });
25
+ }
26
+
27
+ createSortOrder() {
28
+ let _sortOrder = [...this.freqData.entries()];
29
+ timSort(_sortOrder, (a, b) => b[1] - a[1]);
30
+
31
+ this.sortOrder = _sortOrder.map(i => i[0]);
32
+ }
33
+
34
+ sortFromNodeAttrsArray(attrValuesArray) {
35
+ const resultArray = [];
36
+
37
+ if (!this.sortOrder) {
38
+ this.createSortOrder();
39
+ }
40
+
41
+ this.sortOrder.forEach(k => {
42
+ if (attrValuesArray.includes(k)) {
43
+ resultArray.push(k);
44
+ }
45
+ });
46
+
47
+ return resultArray;
48
+ }
49
+ }
50
+
51
+ /** Sort values inside list-like attributes (e.g. class, rel) */
52
+ export default function collapseAttributeWhitespace(tree, options, moduleOptions) {
53
+ const sortType = processModuleOptions(moduleOptions);
54
+
55
+ if (sortType === 'alphabetical') {
56
+ return sortAttributesWithListsInAlphabeticalOrder(tree);
57
+ }
58
+
59
+ if (sortType === 'frequency') {
60
+ return sortAttributesWithListsByFrequency(tree);
61
+ }
62
+
63
+ // Invalid configuration
64
+ return tree;
65
+ }
66
+
67
+ function sortAttributesWithListsInAlphabeticalOrder(tree) {
68
+ tree.walk(node => {
69
+ if (!node.attrs) {
70
+ return node;
71
+ }
72
+
73
+ Object.keys(node.attrs).forEach(attrName => {
74
+ const attrNameLower = attrName.toLowerCase();
75
+ if (!attributesWithLists.has(attrNameLower)) {
76
+ return;
77
+ }
78
+
79
+ const attrValues = node.attrs[attrName].split(/\s/);
80
+
81
+ node.attrs[attrName] = attrValues.sort((a, b) => {
82
+ return typeof a.localeCompare === 'function' ? a.localeCompare(b) : a - b;
83
+ }).join(' ');
84
+ });
85
+
86
+ return node;
87
+ });
88
+
89
+ return tree;
90
+ }
91
+
92
+ function sortAttributesWithListsByFrequency(tree) {
93
+ const tokenChainObj = {}; // <attrNameLower: AttributeTokenChain>[]
94
+
95
+ // Traverse through tree to get frequency
96
+ tree.walk(node => {
97
+ if (!node.attrs) {
98
+ return node;
99
+ }
100
+
101
+ Object.entries(node.attrs).forEach(([attrName, attrValues]) => {
102
+ const attrNameLower = attrName.toLowerCase();
103
+
104
+ if (!attributesWithLists.has(attrNameLower)) {
105
+ return;
106
+ }
107
+
108
+ tokenChainObj[attrNameLower] = tokenChainObj[attrNameLower] || new AttributeTokenChain();
109
+ tokenChainObj[attrNameLower].addFromNodeAttrsArray(attrValues.split(/\s/));
110
+ });
111
+
112
+ return node;
113
+ });
114
+
115
+ // Traverse through tree again, this time sort the attribute values
116
+ tree.walk(node => {
117
+ if (!node.attrs) {
118
+ return node;
119
+ }
120
+
121
+ Object.entries(node.attrs).forEach(([attrName, attrValues]) => {
122
+ const attrNameLower = attrName.toLowerCase();
123
+
124
+ if (!attributesWithLists.has(attrNameLower)) {
125
+ return;
126
+ }
127
+
128
+ if (tokenChainObj[attrNameLower]) {
129
+ node.attrs[attrName] = tokenChainObj[attrNameLower].sortFromNodeAttrsArray(attrValues.split(/\s/)).join(' ');
130
+ }
131
+ });
132
+
133
+ return node;
134
+ });
135
+ }
@@ -4,20 +4,15 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _safe = _interopRequireDefault(require("./safe"));
8
- function _interopRequireDefault(obj) {
9
- return obj && obj.__esModule ? obj : {
10
- default: obj
11
- };
12
- }
7
+ var _safe = _interopRequireDefault(require("./safe.cjs"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
9
  /**
14
10
  * A safe preset for AMP pages (https://www.ampproject.org)
15
11
  */
16
- var _default = {
12
+ var _default = exports.default = {
17
13
  ..._safe.default,
18
14
  collapseBooleanAttributes: {
19
15
  amphtml: true
20
16
  },
21
17
  minifyJs: false
22
- };
23
- exports.default = _default;
18
+ };
@@ -0,0 +1,11 @@
1
+ import safePreset from './safe.mjs';
2
+
3
+ /**
4
+ * A safe preset for AMP pages (https://www.ampproject.org)
5
+ */
6
+ export default { ...safePreset,
7
+ collapseBooleanAttributes: {
8
+ amphtml: true,
9
+ },
10
+ minifyJs: false,
11
+ };
@@ -4,16 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _safe = _interopRequireDefault(require("./safe"));
8
- function _interopRequireDefault(obj) {
9
- return obj && obj.__esModule ? obj : {
10
- default: obj
11
- };
12
- }
7
+ var _safe = _interopRequireDefault(require("./safe.cjs"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
9
  /**
14
10
  * Maximal minification (might break some pages)
15
11
  */
16
- var _default = {
12
+ var _default = exports.default = {
17
13
  ..._safe.default,
18
14
  collapseWhitespace: 'all',
19
15
  removeComments: 'all',
@@ -28,5 +24,4 @@ var _default = {
28
24
  minifySvg: {},
29
25
  minifyConditionalComments: true,
30
26
  removeOptionalTags: true
31
- };
32
- exports.default = _default;
27
+ };
@@ -0,0 +1,20 @@
1
+ import safePreset from './safe.mjs';
2
+
3
+ /**
4
+ * Maximal minification (might break some pages)
5
+ */
6
+ export default { ...safePreset,
7
+ collapseWhitespace: 'all',
8
+ removeComments: 'all',
9
+ removeAttributeQuotes: true,
10
+ removeRedundantAttributes: true,
11
+ mergeScripts: true,
12
+ mergeStyles: true,
13
+ removeUnusedCss: {},
14
+ minifyCss: {
15
+ preset: 'default',
16
+ },
17
+ minifySvg: {},
18
+ minifyConditionalComments: true,
19
+ removeOptionalTags: true,
20
+ };
@@ -7,7 +7,7 @@ exports.default = void 0;
7
7
  /**
8
8
  * Minify HTML in a safe way without breaking anything.
9
9
  */
10
- var _default = {
10
+ var _default = exports.default = {
11
11
  /* ----------------------------------------
12
12
  * Attributes
13
13
  * ---------------------------------------- */
@@ -62,5 +62,4 @@ var _default = {
62
62
  * Miscellaneous
63
63
  * ---------------------------------------- */
64
64
  custom: []
65
- };
66
- exports.default = _default;
65
+ };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Minify HTML in a safe way without breaking anything.
3
+ */
4
+ export default {
5
+ /* ----------------------------------------
6
+ * Attributes
7
+ * ---------------------------------------- */
8
+ // normalize the case of attribute names and values
9
+ // normalizeAttributeValues will also normalize property value with invalid value default
10
+ // See https://html.spec.whatwg.org/#invalid-value-default
11
+ normalizeAttributeValues: true,
12
+ removeEmptyAttributes: true,
13
+ collapseAttributeWhitespace: true,
14
+ // removeRedundantAttributes will remove attributes when missing value default matches the attribute's value
15
+ // See https://html.spec.whatwg.org/#missing-value-default
16
+ removeRedundantAttributes: false,
17
+ // collapseBooleanAttributes will also collapse those default state can be omitted
18
+ collapseBooleanAttributes: {
19
+ amphtml: false,
20
+ },
21
+ deduplicateAttributeValues: true,
22
+
23
+ minifyUrls: false,
24
+
25
+ sortAttributes: false,
26
+ sortAttributesWithLists: 'alphabetical',
27
+
28
+ /* ----------------------------------------
29
+ * Minify HTML content
30
+ * ---------------------------------------- */
31
+ collapseWhitespace: 'conservative',
32
+ removeComments: 'safe',
33
+ minifyConditionalComments: false,
34
+ removeOptionalTags: false,
35
+ removeAttributeQuotes: false,
36
+ /* ----------------------------------------
37
+ * Minify inline <style>, <script> and <svg> tag
38
+ * ---------------------------------------- */
39
+ mergeStyles: false,
40
+ mergeScripts: false,
41
+ minifyCss: {
42
+ preset: 'default',
43
+ },
44
+ minifyJs: {},
45
+ minifyJson: {},
46
+ minifySvg: {
47
+ plugins: [
48
+ {
49
+ name: 'preset-default',
50
+ params: {
51
+ overrides: {
52
+ collapseGroups: false,
53
+ convertShapeToPath: false,
54
+ },
55
+ },
56
+ },
57
+ ]
58
+ },
59
+ removeUnusedCss: false,
60
+
61
+ /* ----------------------------------------
62
+ * Miscellaneous
63
+ * ---------------------------------------- */
64
+ custom: []
65
+ };
package/package.json CHANGED
@@ -1,14 +1,29 @@
1
1
  {
2
2
  "name": "htmlnano",
3
- "version": "2.0.4",
3
+ "version": "2.1.1",
4
4
  "description": "Modular HTML minifier, built on top of the PostHTML",
5
- "main": "index.js",
5
+ "main": "index.cjs",
6
+ "module": "index.mjs",
7
+ "source": "index.mjs",
8
+ "exports": {
9
+ ".": {
10
+ "require": "./index.cjs",
11
+ "import": "./index.mjs"
12
+ },
13
+ "./index.mjs": {
14
+ "import": "./index.mjs"
15
+ },
16
+ "./index.cjs": {
17
+ "require": "./index.cjs"
18
+ }
19
+ },
6
20
  "types": "index.d.ts",
7
21
  "author": "Kirill Maltsev <maltsevkirill@gmail.com>",
8
22
  "license": "MIT",
9
23
  "scripts": {
10
- "compile": "rimraf lib/*.js && rimraf lib/modules/*.js && babel -d lib/ lib/",
11
- "lint": "eslint *.js lib/*.es6 lib/modules/*.es6 lib/presets/*.es6 test/",
24
+ "clean": "rimraf lib/*.cjs lib/**/*.cjs",
25
+ "compile": "npm run clean && babel -d lib/ lib/ --out-file-extension .cjs",
26
+ "lint": "eslint --fix *.mjs lib/*.mjs lib/**/*.mjs test/*.mjs test/**/*.mjs",
12
27
  "pretest": "npm run lint && npm run compile",
13
28
  "test": ":",
14
29
  "posttest": "mocha --timeout 5000 --require @babel/register --recursive --check-leaks --globals addresses",
@@ -31,10 +46,20 @@
31
46
  }
32
47
  }
33
48
  ]
49
+ ],
50
+ "plugins": [
51
+ [
52
+ "@aminya/babel-plugin-replace-import-extension",
53
+ {
54
+ "extMapping": {
55
+ ".mjs": ".cjs"
56
+ }
57
+ }
58
+ ]
34
59
  ]
35
60
  },
36
61
  "dependencies": {
37
- "cosmiconfig": "^8.0.0",
62
+ "cosmiconfig": "^9.0.0",
38
63
  "posthtml": "^0.16.5",
39
64
  "timsort": "^0.3.0"
40
65
  },
@@ -44,25 +69,28 @@
44
69
  "@babel/eslint-parser": "^7.17.0",
45
70
  "@babel/preset-env": "^7.15.6",
46
71
  "@babel/register": "^7.15.3",
47
- "cssnano": "^6.0.0",
72
+ "@aminya/babel-plugin-replace-import-extension": "1.2.0",
73
+ "cssnano": "^7.0.0",
48
74
  "eslint": "^8.12.0",
75
+ "eslint-plugin-import": "^2.28.1",
76
+ "eslint-plugin-path-import-extension": "^0.9.0",
49
77
  "expect": "^29.0.0",
50
78
  "mocha": "^10.1.0",
51
79
  "postcss": "^8.3.11",
52
- "purgecss": "^5.0.0",
80
+ "purgecss": "^6.0.0",
53
81
  "relateurl": "^0.2.7",
54
82
  "rimraf": "^5.0.0",
55
- "srcset": "4.0.0",
83
+ "srcset": "5.0.1",
56
84
  "svgo": "^3.0.2",
57
- "terser": "^5.10.0",
85
+ "terser": "^5.21.0",
58
86
  "uncss": "^0.17.3"
59
87
  },
60
88
  "peerDependencies": {
61
- "cssnano": "^6.0.0",
89
+ "cssnano": "^7.0.0",
62
90
  "postcss": "^8.3.11",
63
- "purgecss": "^5.0.0",
91
+ "purgecss": "^6.0.0",
64
92
  "relateurl": "^0.2.7",
65
- "srcset": "4.0.0",
93
+ "srcset": "5.0.1",
66
94
  "svgo": "^3.0.2",
67
95
  "terser": "^5.10.0",
68
96
  "uncss": "^0.17.3"
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./lib/htmlnano').default;