From f384973fe64a72d3d76ca605270fb2344c79f3d9 Mon Sep 17 00:00:00 2001 From: Thorn Walli Date: Tue, 13 Jun 2023 13:12:00 +0200 Subject: [PATCH] fix(update): update preload optimization - added package `@nuxtjs/critters` --- build.config.mjs | 16 +- package-lock.json | 713 ++++++++++++++--------------------- package.json | 8 +- playground/nuxt.config.mjs | 22 +- src/hookFunctions.mjs | 31 -- src/module.mjs | 71 ++-- src/utils.mjs | 185 ++++----- src/utils/options.mjs | 44 +++ src/utils/preload.mjs | 28 ++ test/tests/html.mjs | 22 +- test/{utils.js => utils.mjs} | 2 +- 11 files changed, 485 insertions(+), 657 deletions(-) delete mode 100644 src/hookFunctions.mjs create mode 100644 src/utils/options.mjs create mode 100644 src/utils/preload.mjs rename test/{utils.js => utils.mjs} (98%) diff --git a/build.config.mjs b/build.config.mjs index e4e3cc04cb..a96a13a227 100644 --- a/build.config.mjs +++ b/build.config.mjs @@ -4,15 +4,23 @@ export default { 'glob', 'consola', 'change-case', - 'pathe', 'hash-sum', + 'probe-image-size', + 'vue3-lazy-hydration', + + // package + '@nuxt/image', + '@nuxtjs/critters', 'browserslist-useragent-regexp', - 'deepmerge', + 'cheerio', 'defu', + 'dom-serializer', 'dynamic-class-list', - 'probe-image-size', + 'htmlparser2', + 'image-meta', + 'pathe', 'serialize-to-js', 'sort-css-media-queries', - 'vue-lazy-hydration' + 'vue3-lazy-hydration' ] }; diff --git a/package-lock.json b/package-lock.json index 0bad3f5bec..2244f95456 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,13 @@ "license": "MIT", "dependencies": { "@nuxt/image": "1.0.0-rc.1", + "@nuxtjs/critters": "^0.4.1", "browserslist-useragent-regexp": "4.0.0", - "deepmerge": "4.3.1", + "cheerio": "^1.0.0-rc.12", "defu": "6.1.2", + "dom-serializer": "^2.0.0", "dynamic-class-list": "2.0.2", + "htmlparser2": "^9.0.0", "image-meta": "0.1.1", "pathe": "1.1.1", "serialize-to-js": "3.1.2", @@ -64,9 +67,6 @@ "stylelint-config-standard": "33.0.0", "vite-svg-loader": "4.0.0", "vitest": "0.32.0", - "vue-headings": "1.0.0", - "vue-svg-loader": "0.16.0", - "webpack-bundle-analyzer": "4.9.0", "wicg-inert": "3.1.2" } }, @@ -3510,6 +3510,21 @@ "vue": "^3.3.4" } }, + "node_modules/@nuxtjs/critters": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxtjs/critters/-/critters-0.4.1.tgz", + "integrity": "sha512-5l4xkaC5v9vXBAyhdQZgG81hntlzZpCZ6z/6VrJBApOVjWr3dDgCpVb7hAODXHbTxemnSec9KCvbtcIxBytwFA==", + "dependencies": { + "@nuxt/kit": "^3.4.2", + "critters": "0.0.16", + "pathe": "1.1.0" + } + }, + "node_modules/@nuxtjs/critters/node_modules/pathe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.0.tgz", + "integrity": "sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==" + }, "node_modules/@nuxtjs/eslint-config": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@nuxtjs/eslint-config/-/eslint-config-12.0.0.tgz", @@ -3992,12 +4007,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", - "dev": true - }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -5037,25 +5046,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -5265,8 +5255,7 @@ "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -5616,6 +5605,72 @@ "node": "*" } }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/cheerio/node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -5867,20 +5922,6 @@ "node": ">=0.10.0" } }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -6230,6 +6271,162 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/critters": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", + "integrity": "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==", + "dependencies": { + "chalk": "^4.1.0", + "css-select": "^4.2.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "postcss": "^8.3.7", + "pretty-bytes": "^5.3.0" + } + }, + "node_modules/critters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/critters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/critters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/critters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/critters/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/critters/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/critters/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/critters/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/critters/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/critters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/critters/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/critters/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/critters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cross-fetch": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", @@ -6438,7 +6635,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -6450,12 +6646,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -6473,7 +6663,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, "engines": { "node": ">= 6" }, @@ -6690,13 +6879,6 @@ "node": ">=6" } }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true, - "peer": true - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -6799,6 +6981,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6959,7 +7142,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -6973,7 +7155,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -6997,7 +7178,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "dependencies": { "domelementtype": "^2.3.0" }, @@ -7012,7 +7192,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -7134,7 +7313,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -7219,12 +7397,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "node_modules/es-module-lexer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", @@ -8602,19 +8774,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -9955,16 +10114,6 @@ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "peer": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", @@ -10031,10 +10180,9 @@ } }, "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz", + "integrity": "sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -10045,8 +10193,8 @@ "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/http-errors": { @@ -13657,7 +13805,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -13933,25 +14080,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", @@ -14341,7 +14469,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, "dependencies": { "entities": "^4.4.0" }, @@ -14349,6 +14476,19 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -14954,6 +15094,25 @@ "node": "^12 || >=14" } }, + "node_modules/postcss-html/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/postcss-html/node_modules/js-tokens": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.1.tgz", @@ -16814,30 +16973,6 @@ "tslib": "^2.1.0" } }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -16887,12 +17022,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -17357,19 +17486,6 @@ "readable-stream": "^3.0.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -17889,198 +18005,6 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, - "node_modules/svg-to-vue": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/svg-to-vue/-/svg-to-vue-0.7.0.tgz", - "integrity": "sha512-Tg2nMmf3BQorYCAjxbtTkYyWPVSeox5AZUFvfy4MoWK/5tuQlnA/h3LAlTjV3sEvOC5FtUNovRSj3p784l4KOA==", - "dev": true, - "dependencies": { - "svgo": "^1.3.2" - }, - "peerDependencies": { - "vue-template-compiler": "^2.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/svg-to-vue/node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/svg-to-vue/node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svg-to-vue/node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/svg-to-vue/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/svg-to-vue/node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/svg-to-vue/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/svg-to-vue/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/svg-to-vue/node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "node_modules/svg-to-vue/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/svg-to-vue/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/svg-to-vue/node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/svgo": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", @@ -19374,12 +19298,6 @@ "node": ">=10.13.0" } }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", - "dev": true - }, "node_modules/unstorage": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.6.1.tgz", @@ -19594,21 +19512,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -20500,12 +20403,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/vue-headings": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vue-headings/-/vue-headings-1.0.0.tgz", - "integrity": "sha512-Fczo4DQgzZUJT9T2ih4OLX3n4Yj9MFQFbnKNSBZyv0y9NmdZy8jAEBBNKYvOujfswc4lpIXkLT2km15NBAlhbA==", - "dev": true - }, "node_modules/vue-loader": { "version": "17.2.2", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.2.2.tgz", @@ -20613,56 +20510,6 @@ "vue": "^3.2.0" } }, - "node_modules/vue-svg-loader": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/vue-svg-loader/-/vue-svg-loader-0.16.0.tgz", - "integrity": "sha512-2RtFXlTCYWm8YAEO2qAOZ2SuIF2NvLutB5muc3KDYoZq5ZeCHf8ggzSan3ksbbca7CJ/Aw57ZnDF4B7W/AkGtw==", - "dev": true, - "dependencies": { - "loader-utils": "^1.2.3", - "svg-to-vue": "^0.7.0" - }, - "peerDependencies": { - "vue-template-compiler": "^2.0.0" - } - }, - "node_modules/vue-svg-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/vue-svg-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/vue-template-compiler": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz", - "integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==", - "dev": true, - "peer": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, "node_modules/vue3-lazy-hydration": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/vue3-lazy-hydration/-/vue3-lazy-hydration-1.2.1.tgz", diff --git a/package.json b/package.json index e495215532..bd315e072e 100644 --- a/package.json +++ b/package.json @@ -49,10 +49,13 @@ ], "dependencies": { "@nuxt/image": "1.0.0-rc.1", + "@nuxtjs/critters": "^0.4.1", "browserslist-useragent-regexp": "4.0.0", - "deepmerge": "4.3.1", + "cheerio": "^1.0.0-rc.12", "defu": "6.1.2", + "dom-serializer": "^2.0.0", "dynamic-class-list": "2.0.2", + "htmlparser2": "^9.0.0", "image-meta": "0.1.1", "pathe": "1.1.1", "serialize-to-js": "3.1.2", @@ -102,9 +105,6 @@ "stylelint-config-standard": "33.0.0", "vite-svg-loader": "4.0.0", "vitest": "0.32.0", - "vue-headings": "1.0.0", - "vue-svg-loader": "0.16.0", - "webpack-bundle-analyzer": "4.9.0", "wicg-inert": "3.1.2" } } diff --git a/playground/nuxt.config.mjs b/playground/nuxt.config.mjs index 155075a8bf..6fd8f10d32 100644 --- a/playground/nuxt.config.mjs +++ b/playground/nuxt.config.mjs @@ -20,7 +20,7 @@ export default defineNuxtConfig(async () => { builder: getBuilder(), - ssr: hasTargetStatic(), + ssr: true, runtimeConfig: { public: { @@ -69,10 +69,6 @@ export default defineNuxtConfig(async () => { order: 'cssnanoLast' }, - generate: { - dir: getDistPath() - }, - router: { base: getBasePath(), strict: undefined @@ -111,6 +107,7 @@ export default defineNuxtConfig(async () => { }, speedkit: { + // targetFormats: ['jpg|jpeg|png|gif'], detection: { performance: true, browserSupport: true @@ -388,7 +385,7 @@ export default defineNuxtConfig(async () => { ] }, - modules: ['../src/module', '@nuxtjs/fontaine'], + modules: ['../src/module'], head: { htmlAttrs: { @@ -423,16 +420,3 @@ function getHost() { function getPort() { return process.env.npm_config_port || process.env.PORT || 3000; } - -function getDistPath() { - return process.env.npm_config_dist || process.env.DIST_PATH || 'dist'; -} - -function hasTargetStatic() { - return ( - (process.argv.indexOf('--target') && - process.argv[process.argv.indexOf('--target') + 1] === 'static') || - process.env.npm_config_target_static || - process.env.TARGET_STATIC - ); -} diff --git a/src/hookFunctions.mjs b/src/hookFunctions.mjs deleted file mode 100644 index 3eef318eae..0000000000 --- a/src/hookFunctions.mjs +++ /dev/null @@ -1,31 +0,0 @@ -import { join } from 'pathe'; -import { logger } from './utils.mjs'; - -function autoImportComponents(nuxt, componentsDir, componentPrefix) { - nuxt.hook('components:dirs', dirs => { - dirs.push( - { path: componentsDir, pattern: '*', prefix: componentPrefix }, - { - path: join(componentsDir, 'abstracts'), - pattern: '*', - prefix: `${componentPrefix || ''}Abstract` - } - ); - }); -} - -function preloadOptimization() { - return resources => { - logger.info('TODO: Implement preloadOptimization hook'); - // ['clientManifest', 'modernManifest'].filter(value => resources[String(value)]).forEach((key) => { - // const assetsMapping = resources[String(key)].assetsMapping; - // for (const assetKey in assetsMapping) { - // if (assetsMapping[String(assetKey)].length > 1) { - // delete assetsMapping[String(assetKey)]; - // } - // } - // }); - }; -} - -export { autoImportComponents, preloadOptimization }; diff --git a/src/module.mjs b/src/module.mjs index 89d3fd1f96..bef8808521 100644 --- a/src/module.mjs +++ b/src/module.mjs @@ -4,31 +4,29 @@ import { createResolver, defineNuxtModule, addPluginTemplate, - addTemplate, - // isNuxt3, - installModule, - logger + addTemplate } from '@nuxt/kit'; import { getCrossorigin } from './runtime/utils.mjs'; import FontConfig from './runtime/classes/FontConfig.mjs'; import { DEFAULT_TARGET_FORMATS, MODULE_NAME, - getDefaultOptions, - getNuxtImageModuleOptions, + addNuxtCritters, + addNuxtFontaine, + addNuxtImage, isWebpackBuild, - optimizeNuxtOptions, - optimizePreloads, + logger, setPublicRuntimeConfig } from './utils.mjs'; -import { getSupportedBrowserDetector } from './utils/browser.mjs'; -import { registerAppEntry as registerAppEntryWebpack } from './hookFunctions/webpack.mjs'; -import { registerAppEntry as registerAppEntryVite } from './hookFunctions/vite.mjs'; - +import { getDefaultOptions } from './utils/options.mjs'; import { getFontConfigTemplate, getFontConfigCSSTemplate } from './utils/template.mjs'; +import { optimizePreloads } from './utils/preload.mjs'; +import { getSupportedBrowserDetector } from './utils/browser.mjs'; +import { registerAppEntry as registerAppEntryWebpack } from './hookFunctions/webpack.mjs'; +import { registerAppEntry as registerAppEntryVite } from './hookFunctions/vite.mjs'; const resolver = createResolver(import.meta.url); @@ -51,11 +49,7 @@ export default defineNuxtModule({ nuxt.options.alias['speedkit-create-sort'] = 'sort-css-media-queries/lib/create-sort.js'; - if (!moduleOptions.disableNuxtImage) { - moduleOptions.targetFormats = - moduleOptions.targetFormats || DEFAULT_TARGET_FORMATS; - await addNuxtImage(nuxt); - } + await addModules(nuxt, moduleOptions); setPublicRuntimeConfig(nuxt, moduleOptions); @@ -77,17 +71,15 @@ export default defineNuxtModule({ } } else { logger( - `[${MODULE_NAME}] module functionality is limited without ssr and performance check` + `Module functionality is limited without ssr and performance check` ); } - optimizeNuxtOptions(nuxt); - if (moduleOptions.optimizePreloads) { optimizePreloads(nuxt); } else { logger.warn( - `[${MODULE_NAME}] preload optimization is disabled by module option \`optimizePreloads\`.` + `Preload optimization is disabled by module option \`optimizePreloads\`.` ); } @@ -169,33 +161,16 @@ async function addBuildTemplates(nuxt, options) { }); } -async function addNuxtImage(nuxt) { - // Check if @nuxt/image exists, if not, module is registered in nuxt. - const modules = [...nuxt.options.modules, ...nuxt.options.buildModules]; - if (!modules.find(module => getModuleName(module) === '@nuxt/image')) { - logger.info( - `[${MODULE_NAME}] added module \`@nuxt/image\`, for more configuration learn more at \`https://image.nuxtjs.org/setup#configure\`` - ); - await installModule('@nuxt/image'); +async function addModules(nuxt, moduleOptions) { + if (!moduleOptions.disableNuxtCritters) { + await addNuxtCritters(nuxt); } - - // Check @nuxt/image Options - nuxt.hook('modules:done', () => { - const nuxtImageOptions = getNuxtImageModuleOptions(nuxt); - if ( - nuxtImageOptions && - ['youtube', 'vimeo'].find(alias => !(alias in nuxtImageOptions.alias)) - ) { - logger.warn( - 'For using `SpeedkitYoutube` and `SpeedkitVimeo` you have to set the required domains & aliases for the `Provider` in the `@nuxt/image` options. \nLearn more https://nuxt-speedkit.grabarzundpartner.dev/setup#nuxtimage' - ); - } - }); -} - -function getModuleName(m) { - if (Array.isArray(m)) { - m = m[0]; + if (!moduleOptions.disableNuxtFontaine) { + await addNuxtFontaine(nuxt); + } + if (!moduleOptions.disableNuxtImage) { + moduleOptions.targetFormats = + moduleOptions.targetFormats || DEFAULT_TARGET_FORMATS; + await addNuxtImage(nuxt); } - return m.meta ? m.meta.name : m; } diff --git a/src/utils.mjs b/src/utils.mjs index 4c812f99f5..59d510073b 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -1,109 +1,104 @@ import { defu } from 'defu'; -import { consola } from 'consola'; -import glob from 'glob'; -import { preloadOptimization } from './hookFunctions.mjs'; +import { installModule, useLogger } from '@nuxt/kit'; -const DEFAULT_TARGET_FORMATS = ['webp', 'avif', 'jpg|jpeg|png|gif']; +export const DEFAULT_TARGET_FORMATS = ['webp', 'avif', 'jpg|jpeg|png|gif']; -const MODULE_NAME = 'nuxt-speedkit'; +export const MODULE_NAME = 'nuxt-speedkit'; -export const logger = consola.withTag(MODULE_NAME); +export const logger = useLogger(MODULE_NAME); -function isWebpackBuild(nuxt) { +function getModuleName(m) { + if (Array.isArray(m)) { + m = m[0]; + } + return m.meta ? m.meta.name : m; +} + +export function isWebpackBuild(nuxt) { return nuxt.options.builder === '@nuxt/webpack-builder'; } -function isViteBuild(nuxt) { +export function isViteBuild(nuxt) { return !isWebpackBuild(nuxt); } -const getDefaultOptions = () => { - return { - debug: false, - - disableNuxtImage: false, // If set, `@nuxt/image` will not be integrated. - - optimizePreloads: true, - - detection: { - performance: true, - browserSupport: true - }, - - performanceMetrics: { - timing: { - fcp: 800, - dcl: 1200 // fallback if fcp is not available (safari) - } - }, - - fonts: [], - - targetFormats: null, - - /** - * IntersectionObserver rootMargin for Compoennts and Assets - */ - lazyOffset: { - component: '0%', - asset: '0%' - } +export const setPublicRuntimeConfig = (nuxt, options) => { + nuxt.options.runtimeConfig.public.speedkit = { + lazyOffsetComponent: options.lazyOffset.component, + lazyOffsetAsset: options.lazyOffset.asset }; }; -function deprecationsNotification(options) { - if ('loader' in options) { - logger.warn( - `[${MODULE_NAME}] Option \`loader\` is deprecated, There is no integrated loader anymore.` +function moduleExists(nuxt, moduleName) { + return ( + nuxt.options.modules && + nuxt.options.modules.find(module => getModuleName(module) === moduleName) + ); +} + +export async function addNuxtCritters(nuxt) { + if (!moduleExists(nuxt, '@nuxtjs/critters')) { + logger.info( + `[${MODULE_NAME}] added module \`@nuxtjs/critters\`, for more configuration learn more at \`https://github.com/nuxt-modules/critters\`` + ); + nuxt.options.critters = defu( + { + config: { + preload: false + } + }, + nuxt.options.critters ); - delete options.loader; + + await installModule('@nuxtjs/critters'); } } -const setPublicRuntimeConfig = (nuxt, options) => { - nuxt.options.runtimeConfig.public.speedkit = { - lazyOffsetComponent: options.lazyOffset.component, - lazyOffsetAsset: options.lazyOffset.asset - }; -}; - -function optimizePreloads(nuxt) { - if (isViteBuild(nuxt)) { - nuxt.options.vite.build.manifest = false; +export async function addNuxtFontaine(nuxt) { + if (!moduleExists(nuxt, '@nuxtjs/fontaine')) { + logger.info( + `[${MODULE_NAME}] added module \`@nuxtjs/fontaine\`, for more configuration learn more at \`https://github.com/nuxt-modules/fontaine\`` + ); + await installModule('@nuxtjs/fontaine'); } - nuxt.options.noScripts = false; - nuxt.hook('build:manifest', preloadOptimization()); } -function optimizeNuxtOptions(nuxt) { - // TODO: https://github.com/nuxt/nuxt/issues/21381 - // if (isWebpackBuild(nuxt)) { - // nuxt.options.webpack.extractCSS = false; - // } else { - // nuxt.options.vite.build.cssCodeSplit = false; - // } +export async function addNuxtImage(nuxt) { + if (!moduleExists(nuxt, '@nuxt/image')) { + logger.info( + `[${MODULE_NAME}] added module \`@nuxt/image\`, for more configuration learn more at \`https://image.nuxtjs.org/setup#configure\`` + ); + await installModule('@nuxt/image'); + } + + // Check @nuxt/image Options + nuxt.hook('modules:done', () => { + const nuxtImageOptions = getNuxtImageModuleOptions(nuxt); + if ( + nuxtImageOptions && + ['youtube', 'vimeo'].find(alias => !(alias in nuxtImageOptions.alias)) + ) { + logger.warn( + 'For using `SpeedkitYoutube` and `SpeedkitVimeo` you have to set the required domains & aliases for the `Provider` in the `@nuxt/image` options. \nLearn more https://nuxt-speedkit.grabarzundpartner.dev/setup#nuxtimage' + ); + } + }); } -function getComponentFiles(cwd) { - return new Promise(resolve => - glob( - '**/*.vue', - { - cwd - }, - (err, files) => { - if (err) { - throw err; - } - resolve(files); - } - ) +export function getNuxtImageModuleOptions(moduleContainer) { + return defu( + { + domains: [], + alias: {}, + screens: {} + }, + getModuleOptions(moduleContainer, '@nuxt/image', 'image') ); } -function getNuxtImageModuleOptions(moduleContainer) { - let imageOptions; - if ('image' in moduleContainer.options) { - imageOptions = moduleContainer.options.image; +export function getModuleOptions(moduleContainer, packageName, configKey) { + let options; + if (configKey in moduleContainer.options) { + options = moduleContainer.options[configKey]; } else { const module = [] .concat( @@ -112,31 +107,9 @@ function getNuxtImageModuleOptions(moduleContainer) { ) .find( module => - Array.isArray(module) && module[0] === '@nuxt/image' && module[1] + Array.isArray(module) && module[0] === packageName && module[1] ); - imageOptions = (module && module[1]) || {}; + options = (module && module[1]) || {}; } - - return defu( - { - domains: [], - alias: {}, - screens: {} - }, - imageOptions - ); + return options; } - -export { - DEFAULT_TARGET_FORMATS, - MODULE_NAME, - deprecationsNotification, - getDefaultOptions, - setPublicRuntimeConfig, - optimizePreloads, - optimizeNuxtOptions, - getComponentFiles, - getNuxtImageModuleOptions, - isWebpackBuild, - isViteBuild -}; diff --git a/src/utils/options.mjs b/src/utils/options.mjs new file mode 100644 index 0000000000..8f9014a0e0 --- /dev/null +++ b/src/utils/options.mjs @@ -0,0 +1,44 @@ +import { MODULE_NAME, logger } from '../utils.mjs'; + +export function getDefaultOptions() { + return { + debug: false, + + disableNuxtImage: false, // If set, `@nuxt/image` will not be integrated. + + optimizePreloads: true, + + detection: { + performance: true, + browserSupport: true + }, + + performanceMetrics: { + timing: { + fcp: 800, + dcl: 1200 // fallback if fcp is not available (safari) + } + }, + + fonts: [], + + targetFormats: null, + + /** + * IntersectionObserver rootMargin for Compoennts and Assets + */ + lazyOffset: { + component: '0%', + asset: '0%' + } + }; +} + +export function deprecationsNotification(options) { + if ('loader' in options) { + logger.warn( + `[${MODULE_NAME}] Option \`loader\` is deprecated, There is no integrated loader anymore.` + ); + delete options.loader; + } +} diff --git a/src/utils/preload.mjs b/src/utils/preload.mjs new file mode 100644 index 0000000000..1d60a3339b --- /dev/null +++ b/src/utils/preload.mjs @@ -0,0 +1,28 @@ +import { parseDocument } from 'htmlparser2'; +import { load } from 'cheerio'; +import { render } from 'dom-serializer'; +import { isViteBuild } from '../utils.mjs'; + +export function optimizePreloads(nuxt) { + if (isViteBuild(nuxt)) { + nuxt.options.vite.build.manifest = false; + } + + nuxt.hook('nitro:init', nitro => { + nitro.hooks.hook('prerender:generate', route => { + if (!route.fileName?.endsWith('.html') || !route.contents) return; + + const document = parseDocument(route.contents); + const $ = load(document); + + $('[rel="modulepreload"][as="script"]').remove(); + $('[rel="prefetch"][as="script"]').remove(); + + $('[rel="preload"][as="style"]').remove(); + $('[rel="prefetch"][as="style"]').remove(); + $('link[rel="stylesheet"]').remove(); + + route.contents = render(document); + }); + }); +} diff --git a/test/tests/html.mjs b/test/tests/html.mjs index c887ae8b5b..2d269247e4 100644 --- a/test/tests/html.mjs +++ b/test/tests/html.mjs @@ -2,7 +2,7 @@ import { join } from 'path'; import { describe, it, expect } from 'vitest'; -import { getDom, getLinkPreloadHid, getHTML } from '../utils'; +import { getDom, getLinkPreloadKey, getHTML } from '../utils.mjs'; export default distDir => { describe('🧐 inspect html', () => { @@ -24,7 +24,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 400, 'normal')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 400, 'normal')}"]` ) ).not.toBeNull(); // element has data attribute? @@ -44,7 +44,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 700, 'normal')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 700, 'normal')}"]` ) ).not.toBeNull(); // element has data attribute? @@ -69,12 +69,12 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 700, 'normal')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 700, 'normal')}"]` ) ).not.toBeNull(); expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 400, 'italic')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 400, 'italic')}"]` ) ).not.toBeNull(); // element has data attribute? @@ -96,7 +96,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 400, 'italic')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 400, 'italic')}"]` ) ).not.toBeNull(); // element has data attribute? @@ -118,7 +118,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid('Merriweather', 700, 'italic')}"]` + `link[data-key="${getLinkPreloadKey('Merriweather', 700, 'italic')}"]` ) ).not.toBeNull(); // element has data attribute? @@ -142,7 +142,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid( + `link[data-key="${getLinkPreloadKey( 'Merriweather', 700, 'italic', @@ -167,7 +167,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid( + `link[data-key="${getLinkPreloadKey( 'Merriweather', 400, 'normal', @@ -190,7 +190,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid( + `link[data-key="${getLinkPreloadKey( 'Merriweather', 400, 'italic', @@ -215,7 +215,7 @@ function markupTests(distDir) { // font link preload exists? expect( dom.head.querySelector( - `link[data-key="${getLinkPreloadHid( + `link[data-key="${getLinkPreloadKey( 'Merriweather', 700, 'normal', diff --git a/test/utils.js b/test/utils.mjs similarity index 98% rename from test/utils.js rename to test/utils.mjs index a63d3922bd..fc9eed3862 100644 --- a/test/utils.js +++ b/test/utils.mjs @@ -23,7 +23,7 @@ export const getFontFaceSnippet = ( ].join('\n'); }; -export const getLinkPreloadHid = ( +export const getLinkPreloadKey = ( family, weight = 400, style = 'normal',