diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index ba75460eec..b09eb26977 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -58,8 +58,8 @@ "@nuxt/telemetry": "^2.3.2", "@nuxt/ui-templates": "^1.3.1", "@nuxt/vite-builder": "workspace:../vite", - "@unhead/ssr": "^1.1.35", - "@unhead/vue": "^1.1.35", + "@unhead/ssr": "^1.2.1", + "@unhead/vue": "^1.2.1", "@vue/shared": "^3.3.4", "acorn": "8.10.0", "c12": "^1.4.2", diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index fa8f83118d..dfbba3cc31 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -54,6 +54,10 @@ export default defineNuxtModule({ addPlugin({ src: resolve(runtimeDir, 'plugins/vueuse-head-polyfill') }) } + if (nuxt.options.experimental.headCapoPlugin) { + addPlugin({ src: resolve(runtimeDir, 'plugins/capo') }) + } + // Add library-specific plugin addPlugin({ src: resolve(runtimeDir, 'plugins/unhead') }) } diff --git a/packages/nuxt/src/head/runtime/plugins/capo.ts b/packages/nuxt/src/head/runtime/plugins/capo.ts new file mode 100644 index 0000000000..548a6e5bd4 --- /dev/null +++ b/packages/nuxt/src/head/runtime/plugins/capo.ts @@ -0,0 +1,9 @@ +import { CapoPlugin, injectHead } from '@unhead/vue' +import { defineNuxtPlugin } from '#app/nuxt' + +export default defineNuxtPlugin({ + name: 'nuxt:head:capo', + setup () { + injectHead().use(CapoPlugin()) + } +}) diff --git a/packages/schema/package.json b/packages/schema/package.json index 2379d5f0c7..a1a285381a 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -30,7 +30,7 @@ "@types/file-loader": "5.0.1", "@types/pug": "2.0.6", "@types/sass-loader": "8.0.5", - "@unhead/schema": "1.1.35", + "@unhead/schema": "1.2.1", "@vitejs/plugin-vue": "4.2.3", "@vitejs/plugin-vue-jsx": "3.0.1", "@vue/compiler-core": "3.3.4", diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index 5399ed7724..f81a145311 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -207,6 +207,11 @@ export default defineUntypedSchema({ * @see https://github.com/parcel-bundler/watcher * @type {'chokidar' | 'parcel' | 'chokidar-granular'} */ - watcher: 'chokidar-granular' + watcher: 'chokidar-granular', + + /** + * Add the CAPO head plugin in order to render tags in of the head in a more performant way. + */ + headCapoPlugin: false } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21820af6f9..466ff6aa95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -359,11 +359,11 @@ importers: specifier: ^14.18.0 || >=16.10.0 version: 18.17.1 '@unhead/ssr': - specifier: ^1.1.35 - version: 1.1.35 + specifier: ^1.2.1 + version: 1.2.1 '@unhead/vue': - specifier: ^1.1.35 - version: 1.1.35(vue@3.3.4) + specifier: ^1.2.1 + version: 1.2.1(vue@3.3.4) '@vue/shared': specifier: ^3.3.4 version: 3.3.4 @@ -568,8 +568,8 @@ importers: specifier: 8.0.5 version: 8.0.5 '@unhead/schema': - specifier: 1.1.35 - version: 1.1.35 + specifier: 1.2.1 + version: 1.2.1 '@vitejs/plugin-vue': specifier: 4.2.3 version: 4.2.3(vite@4.4.7)(vue@3.3.4) @@ -988,7 +988,7 @@ importers: version: 1.1.1 vitest: specifier: latest - version: 0.33.0(happy-dom@10.5.2) + version: 0.34.0(happy-dom@10.5.2) vue: specifier: 3.3.4 version: 3.3.4 @@ -2789,41 +2789,41 @@ packages: eslint-visitor-keys: 3.4.2 dev: true - /@unhead/dom@1.1.35: - resolution: {integrity: sha512-/VAwHHiZGHAKS9V0JaYBWxIBc8OpPMfjVk0TRcKoerFCmYRMsuWtpWauWx644j177kCbzCCT1HOA2fB7R07uXQ==} + /@unhead/dom@1.2.1: + resolution: {integrity: sha512-Kjo6bJpo2RFUlhPq/fGQbUpTdfNSwbwg3vjMmqxCPcTWg87sv+a3kNnIP3c/CV0Sc34OsMY/0Melx+0BAu937g==} dependencies: - '@unhead/schema': 1.1.35 - '@unhead/shared': 1.1.35 + '@unhead/schema': 1.2.1 + '@unhead/shared': 1.2.1 dev: false - /@unhead/schema@1.1.35: - resolution: {integrity: sha512-hB1uHbK38+WoZn2PHRl0eJJ2Lip374+eHHxUbHY4rFQeL4mTgxAFL0KltpMZr5Eo7ZMV/zNL7LZ89KBd9L43Zg==} + /@unhead/schema@1.2.1: + resolution: {integrity: sha512-b0NVAXqFEP2K5Tu3Zkv+MUGnwDMjetEEa8Dw4i0z4rrO3J5Kg1TCp4C+wWCx2d8M6US6yI1TE636K9ll8WophQ==} dependencies: hookable: 5.5.3 zhead: 2.0.10 - /@unhead/shared@1.1.35: - resolution: {integrity: sha512-SmR2tyAVYfvN+bPp71Bp4igHpv19X6VAoVP14qq3Yqdw1nWJKknla2QEkpqAgygit9b69Gyu+Wi5WABpZKUA+A==} + /@unhead/shared@1.2.1: + resolution: {integrity: sha512-tZa/vm2LKoaduPIaol/lQQSX1eY0YCqoktHDO+Vyc9hhoT/oqP2L9LbUjgunQysxbAPKLsgqS0rrXGP+j1fShw==} dependencies: - '@unhead/schema': 1.1.35 + '@unhead/schema': 1.2.1 dev: false - /@unhead/ssr@1.1.35: - resolution: {integrity: sha512-VFIWcqGX358v05tzEPgZ8N7YhAhrrGxeecmRVE/jHtwimKCXa/xsQnhHe5ytswDiuTCTd/qBHEqVTVg8tGseUg==} + /@unhead/ssr@1.2.1: + resolution: {integrity: sha512-Bho966xG896mfq/8QxN8kkWJhju+pwTZLc6Z3ixKUnYshXAYHocxRpbRJYGZaqnIDAFeIPX9pkhuXfQJ6NuAVA==} dependencies: - '@unhead/schema': 1.1.35 - '@unhead/shared': 1.1.35 + '@unhead/schema': 1.2.1 + '@unhead/shared': 1.2.1 dev: false - /@unhead/vue@1.1.35(vue@3.3.4): - resolution: {integrity: sha512-U0iM9B8pq06FS1DLK7g25+ddMqDnQkqy+fgQyC0Gv+e4m8XEKsI7JKSbzAjFnsG69orCKd8M6jvcOyst8gvn5g==} + /@unhead/vue@1.2.1(vue@3.3.4): + resolution: {integrity: sha512-UwL4SSn2Mwe6iNHg/KryDVGGPMp3PR56rl6l5j5+W3oii1E3ZgJk7sNUCcKrOkfITirU2IAkmdfiDfQdc0KTow==} peerDependencies: vue: '>=2.7 || >=3' dependencies: - '@unhead/schema': 1.1.35 - '@unhead/shared': 1.1.35 + '@unhead/schema': 1.2.1 + '@unhead/shared': 1.2.1 hookable: 5.5.3 - unhead: 1.1.35 + unhead: 1.2.1 vue: 3.3.4 dev: false @@ -2880,6 +2880,14 @@ packages: chai: 4.3.7 dev: true + /@vitest/expect@0.34.0: + resolution: {integrity: sha512-d1ZU0XomWFAFyYIc6uNuY0N8NJIWESyO/6ZmwLvlHZw0GevH4AEEpq178KjXIvSCrbHN0GnzYzitd0yjfy7+Ow==} + dependencies: + '@vitest/spy': 0.34.0 + '@vitest/utils': 0.34.0 + chai: 4.3.7 + dev: true + /@vitest/runner@0.33.0: resolution: {integrity: sha512-UPfACnmCB6HKRHTlcgCoBh6ppl6fDn+J/xR8dTufWiKt/74Y9bHci5CKB8tESSV82zKYtkBJo9whU3mNvfaisg==} dependencies: @@ -2888,6 +2896,14 @@ packages: pathe: 1.1.1 dev: true + /@vitest/runner@0.34.0: + resolution: {integrity: sha512-xaqM+oArJothtYXzy/dwu/iHe93Khq5QkvnYbzTxiLA0enD2peft1cask3yE6cJpwMkr7C2D1uMJwnTt4mquDw==} + dependencies: + '@vitest/utils': 0.34.0 + p-limit: 4.0.0 + pathe: 1.1.1 + dev: true + /@vitest/snapshot@0.33.0: resolution: {integrity: sha512-tJjrl//qAHbyHajpFvr8Wsk8DIOODEebTu7pgBrP07iOepR5jYkLFiqLq2Ltxv+r0uptUb4izv1J8XBOwKkVYA==} dependencies: @@ -2896,12 +2912,26 @@ packages: pretty-format: 29.6.2 dev: true + /@vitest/snapshot@0.34.0: + resolution: {integrity: sha512-eGN5XBZHYOghxCOQbf8dcn6/3g7IW77GOOOC/mNFYwRXsPeoQgcgWnhj+6wgJ04pVv25wpxWL9jUkzaQ7LoFtg==} + dependencies: + magic-string: 0.30.2 + pathe: 1.1.1 + pretty-format: 29.6.2 + dev: true + /@vitest/spy@0.33.0: resolution: {integrity: sha512-Kv+yZ4hnH1WdiAkPUQTpRxW8kGtH8VRTnus7ZTGovFYM1ZezJpvGtb9nPIjPnptHbsyIAxYZsEpVPYgtpjGnrg==} dependencies: tinyspy: 2.1.1 dev: true + /@vitest/spy@0.34.0: + resolution: {integrity: sha512-0SZaWrQvL9ZiF/uJvyWSvsKjfuMvD1M6dE5BbE4Dmt8Vh3k4htwCV8g3ce8YOYmJSxkbh6TNOpippD6NVsxW6w==} + dependencies: + tinyspy: 2.1.1 + dev: true + /@vitest/ui@0.33.0(vitest@0.33.0): resolution: {integrity: sha512-7gbAjLqt30R4bodkJAutdpy4ncv+u5IKTHYTow1c2q+FOxZUC9cKOSqMUxjwaaTwLN+EnDnmXYPtg3CoahaUzQ==} peerDependencies: @@ -2925,6 +2955,14 @@ packages: pretty-format: 29.6.2 dev: true + /@vitest/utils@0.34.0: + resolution: {integrity: sha512-IktrDLhBKf3dEUUxH+lcHiPnaw952+GdGvoxg99liMscgP6IePf6LuMY7B9dEIHkFunB1R8VMR/wmI/4UGg1aw==} + dependencies: + diff-sequences: 29.4.3 + loupe: 2.3.6 + pretty-format: 29.6.2 + dev: true + /@volar/language-core@1.10.0: resolution: {integrity: sha512-ddyWwSYqcbEZNFHm+Z3NZd6M7Ihjcwl/9B5cZd8kECdimVXUFdFi60XHWD27nrWtUQIsUYIG7Ca1WBwV2u2LSQ==} dependencies: @@ -6165,7 +6203,7 @@ packages: graceful-fs: 4.2.11 /jstransformer@1.0.0: - resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + resolution: {integrity: sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=} dependencies: is-promise: 2.2.2 promise: 7.3.1 @@ -8459,6 +8497,11 @@ packages: engines: {node: '>=14.0.0'} dev: true + /tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + dev: true + /tinyspy@2.1.1: resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} engines: {node: '>=14.0.0'} @@ -8488,7 +8531,7 @@ packages: engines: {node: '>=0.6'} /token-stream@1.0.0: - resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + resolution: {integrity: sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=} dev: false /totalist@1.1.0: @@ -8662,12 +8705,12 @@ packages: node-fetch-native: 1.2.0 pathe: 1.1.1 - /unhead@1.1.35: - resolution: {integrity: sha512-YEHXxJeSM313yPRcJdBQOSCnkcck1uhg7e2ZoEO+X0KVLuhqV1iYXU+tzvLU+ZId6IZOcEVDfsJ0hHfLkM6Itw==} + /unhead@1.2.1: + resolution: {integrity: sha512-Ox00j8my2mcTa5RtCbLexuIUAOxAQnQ2z/t8l7lHcAw4f5Ewq8vLaRYg/2Y+2WAXVC4ab+am2kYf/Sjj6VBpSw==} dependencies: - '@unhead/dom': 1.1.35 - '@unhead/schema': 1.1.35 - '@unhead/shared': 1.1.35 + '@unhead/dom': 1.2.1 + '@unhead/schema': 1.2.1 + '@unhead/shared': 1.2.1 hookable: 5.5.3 dev: false @@ -8860,6 +8903,28 @@ packages: - supports-color - terser + /vite-node@0.34.0(@types/node@18.17.1): + resolution: {integrity: sha512-rGZMvpb052rjUwJA/a17xMfOibzNF7byMdRSTcN2Lw8uxX08s5EfjWW5mBkm3MSFTPctMSVtT2yC+8ShrZbT5g==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.4.0 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.4.7(@types/node@18.17.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite-plugin-checker@0.6.1(eslint@8.46.0)(typescript@5.1.6)(vite@4.4.7)(vue-tsc@1.8.8): resolution: {integrity: sha512-4fAiu3W/IwRJuJkkUZlWbLunSzsvijDf0eDN6g/MGh6BUK4SMclOTGbLJCPvdAcMOQvVmm8JyJeYLYd4//8CkA==} engines: {node: '>=14.16'} @@ -9047,6 +9112,72 @@ packages: - terser dev: true + /vitest@0.34.0(happy-dom@10.5.2): + resolution: {integrity: sha512-8Pnc1fVt1P6uBncdUZ++hgiJGgxIRKuz4bmS/PQziaEcUj0D1g9cGiR1MbLrcsvFTC6fgrqDhYoTAdBG356WMA==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 18.17.1 + '@vitest/expect': 0.34.0 + '@vitest/runner': 0.34.0 + '@vitest/snapshot': 0.34.0 + '@vitest/spy': 0.34.0 + '@vitest/utils': 0.34.0 + acorn: 8.10.0 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4 + happy-dom: 10.5.2 + local-pkg: 0.4.3 + magic-string: 0.30.2 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.7.0 + vite: 4.4.7(@types/node@18.17.1) + vite-node: 0.34.0(@types/node@18.17.1) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 3f6ea0c161..dc1ddc8722 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -35,7 +35,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"64.4k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) - expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2330k"') + expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2331k"') const packages = modules.files .filter(m => m.endsWith('package.json')) @@ -95,7 +95,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"370k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) - expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"591k"') + expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"593k"') const packages = modules.files .filter(m => m.endsWith('package.json'))