diff --git a/package.json b/package.json index 8b874c308..411c77601 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "clipboardy": "^4.0.0", "consola": "^3.3.3", "defu": "^6.1.4", - "destr": "^2.0.3", "eslint": "^9.17.0", "execa": "^9.5.2", "fuse.js": "^7.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6f7e4de2e..14192e1a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,9 +55,6 @@ importers: defu: specifier: ^6.1.4 version: 6.1.4 - destr: - specifier: ^2.0.3 - version: 2.0.3 eslint: specifier: ^9.17.0 version: 9.17.0(jiti@2.4.2) @@ -138,7 +135,7 @@ importers: version: 1.5.4 unbuild: specifier: ^3.2.0 - version: 3.2.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)) + version: 3.2.0(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)) unplugin-purge-polyfills: specifier: ^0.0.7 version: 0.0.7(rollup@4.30.0) @@ -153,7 +150,7 @@ importers: version: link:.. nuxt: specifier: ^3.15.1 - version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0) + version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.7.0) packages: @@ -1343,6 +1340,15 @@ packages: '@vitest/utils@2.1.8': resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + '@volar/language-core@2.4.11': + resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==} + + '@volar/source-map@2.4.11': + resolution: {integrity: sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==} + + '@volar/typescript@2.4.11': + resolution: {integrity: sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==} + '@vue-macros/common@1.15.1': resolution: {integrity: sha512-O0ZXaladWXwHplQnSjxLbB/G1KpdWCUNJPNYVHIxHonGex1BGpoB4fBZZLgddHgAiy18VZG/Iu5L0kwG+SV7JQ==} engines: {node: '>=16.14.0'} @@ -1380,6 +1386,9 @@ packages: '@vue/compiler-ssr@3.5.13': resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} @@ -1394,6 +1403,14 @@ packages: '@vue/devtools-shared@7.6.8': resolution: {integrity: sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==} + '@vue/language-core@2.2.0': + resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@vue/reactivity@3.5.13': resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} @@ -1445,6 +1462,9 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + alien-signals@0.4.12: + resolution: {integrity: sha512-Og0PgAihxlp1R22bsoBsyhhMG4+qhU+fkkLPoGBQkYVc3qt9rYnrwYTf+M6kqUqUZpf3rXDnpL90iKa0QcSVVg==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -1842,6 +1862,9 @@ packages: mysql2: optional: true + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -2385,6 +2408,10 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -2887,6 +2914,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + nanoid@3.3.8: resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3093,6 +3123,9 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -4237,6 +4270,12 @@ packages: peerDependencies: vue: ^3.2.0 + vue-tsc@2.2.0: + resolution: {integrity: sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + vue@3.5.13: resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: @@ -5090,7 +5129,7 @@ snapshots: - terser - typescript - '@nuxt/vite-builder@3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))(yaml@2.7.0)': + '@nuxt/vite-builder@3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))(yaml@2.7.0)': dependencies: '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.30.0) '@rollup/plugin-replace': 6.0.2(rollup@4.30.0) @@ -5121,7 +5160,7 @@ snapshots: unplugin: 2.1.2 vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0) vite-node: 2.1.8(@types/node@22.10.5)(terser@5.37.0) - vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0)) + vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.7.2)) vue: 3.5.13(typescript@5.7.2) vue-bundle-renderer: 2.1.1 transitivePeerDependencies: @@ -5683,6 +5722,21 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 + '@volar/language-core@2.4.11': + dependencies: + '@volar/source-map': 2.4.11 + optional: true + + '@volar/source-map@2.4.11': + optional: true + + '@volar/typescript@2.4.11': + dependencies: + '@volar/language-core': 2.4.11 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 + optional: true + '@vue-macros/common@1.15.1(rollup@4.30.0)(vue@3.5.13(typescript@5.7.2))': dependencies: '@babel/types': 7.26.3 @@ -5756,6 +5810,12 @@ snapshots: '@vue/compiler-dom': 3.5.13 '@vue/shared': 3.5.13 + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + optional: true + '@vue/devtools-api@6.6.4': {} '@vue/devtools-core@7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.2))': @@ -5784,6 +5844,20 @@ snapshots: dependencies: rfdc: 1.4.1 + '@vue/language-core@2.2.0(typescript@5.7.2)': + dependencies: + '@volar/language-core': 2.4.11 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.13 + alien-signals: 0.4.12 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.7.2 + optional: true + '@vue/reactivity@3.5.13': dependencies: '@vue/shared': 3.5.13 @@ -5838,6 +5912,9 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + alien-signals@0.4.12: + optional: true + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: @@ -6254,6 +6331,9 @@ snapshots: db0@0.2.1: {} + de-indent@1.0.2: + optional: true + debug@2.6.9: dependencies: ms: 2.0.0 @@ -6900,6 +6980,9 @@ snapshots: dependencies: function-bind: 1.1.2 + he@1.2.0: + optional: true + hookable@5.5.3: {} hosted-git-info@2.8.9: {} @@ -7317,7 +7400,7 @@ snapshots: mkdirp@3.0.1: {} - mkdist@2.2.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)): + mkdist@2.2.0(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)): dependencies: autoprefixer: 10.4.20(postcss@8.4.49) citty: 0.1.6 @@ -7335,6 +7418,7 @@ snapshots: optionalDependencies: typescript: 5.7.2 vue: 3.5.13(typescript@5.7.2) + vue-tsc: 2.2.0(typescript@5.7.2) mlly@1.7.3: dependencies: @@ -7351,6 +7435,9 @@ snapshots: ms@2.1.3: {} + muggle-string@0.4.1: + optional: true + nanoid@3.3.8: {} nanoid@5.0.9: {} @@ -7502,14 +7589,14 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0): + nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.7.2))(yaml@2.7.0): dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/devtools': 1.7.0(rollup@4.30.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.2)) '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.30.0) '@nuxt/schema': 3.15.1 '@nuxt/telemetry': 2.6.2(magicast@0.3.5)(rollup@4.30.0) - '@nuxt/vite-builder': 3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))(yaml@2.7.0) + '@nuxt/vite-builder': 3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(magicast@0.3.5)(optionator@0.9.4)(rollup@4.30.0)(terser@5.37.0)(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2))(yaml@2.7.0) '@unhead/dom': 1.11.14 '@unhead/shared': 1.11.14 '@unhead/ssr': 1.11.14 @@ -7761,6 +7848,9 @@ snapshots: parseurl@1.3.3: {} + path-browserify@1.0.1: + optional: true + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -8499,7 +8589,7 @@ snapshots: ultrahtml@1.5.3: {} - unbuild@3.2.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)): + unbuild@3.2.0(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@4.30.0) '@rollup/plugin-commonjs': 28.0.2(rollup@4.30.0) @@ -8514,7 +8604,7 @@ snapshots: hookable: 5.5.3 jiti: 2.4.2 magic-string: 0.30.17 - mkdist: 2.2.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)) + mkdist: 2.2.0(typescript@5.7.2)(vue-tsc@2.2.0(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)) mlly: 1.7.3 pathe: 1.1.2 pkg-types: 1.3.0 @@ -8726,7 +8816,7 @@ snapshots: - supports-color - terser - vite-plugin-checker@0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0)): + vite-plugin-checker@0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.7.2)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0))(vue-tsc@2.2.0(typescript@5.7.2)): dependencies: '@babel/code-frame': 7.26.2 ansi-escapes: 4.3.2 @@ -8747,6 +8837,7 @@ snapshots: eslint: 9.17.0(jiti@2.4.2) optionator: 0.9.4 typescript: 5.7.2 + vue-tsc: 2.2.0(typescript@5.7.2) vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.30.0))(rollup@4.30.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(yaml@2.7.0)): dependencies: @@ -8912,6 +9003,13 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.13(typescript@5.7.2) + vue-tsc@2.2.0(typescript@5.7.2): + dependencies: + '@volar/typescript': 2.4.11 + '@vue/language-core': 2.2.0(typescript@5.7.2) + typescript: 5.7.2 + optional: true + vue@3.5.13(typescript@5.7.2): dependencies: '@vue/compiler-dom': 3.5.13 diff --git a/src/commands/build-module.ts b/src/commands/build-module.ts index fdebb6625..ee9854c9c 100644 --- a/src/commands/build-module.ts +++ b/src/commands/build-module.ts @@ -2,7 +2,7 @@ import { execa } from 'execa' import { consola } from 'consola' import { resolve } from 'pathe' import { defineCommand } from 'citty' -import { tryResolveModule } from '../utils/esm' +import { readPackageJSON } from 'pkg-types' import { cwdArgs, legacyRootDirArgs, logLevelArgs } from './_shared' const MODULE_BUILDER_PKG = '@nuxt/module-builder' @@ -33,10 +33,7 @@ export default defineCommand({ // Find local installed version const cwd = resolve(ctx.args.cwd || ctx.args.rootDir) - const hasLocal = await tryResolveModule( - `${MODULE_BUILDER_PKG}/package.json`, - cwd, - ) + const hasLocal = await readPackageJSON(MODULE_BUILDER_PKG, { url: cwd }) const execArgs = Object.entries({ '--stub': ctx.args.stub, diff --git a/src/commands/build.ts b/src/commands/build.ts index e31cd12bb..a74918ac6 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -33,7 +33,7 @@ export default defineCommand({ const cwd = resolve(ctx.args.cwd || ctx.args.rootDir) - showVersions(cwd) + await showVersions(cwd) const kit = await loadKit(cwd) diff --git a/src/commands/dev.ts b/src/commands/dev.ts index 2f57e84ff..7e3f1c383 100644 --- a/src/commands/dev.ts +++ b/src/commands/dev.ts @@ -13,9 +13,9 @@ import { import type { HTTPSOptions, ListenOptions } from 'listhen' import type { NuxtOptions } from '@nuxt/schema' import { consola } from 'consola' +import { createJiti } from 'jiti' import { showVersions } from '../utils/banner' import { loadKit } from '../utils/kit' -import { importModule } from '../utils/esm' import { overrideEnv } from '../utils/env' import type { NuxtDevContext, NuxtDevIPCMessage } from '../utils/dev' import { envNameArgs, legacyRootDirArgs, dotEnvArgs, cwdArgs, logLevelArgs } from './_shared' @@ -48,7 +48,7 @@ const command = defineCommand({ // Prepare overrideEnv('development') const cwd = resolve(ctx.args.cwd || ctx.args.rootDir) - showVersions(cwd) + await showVersions(cwd) await setupDotenv({ cwd, fileName: ctx.args.dotenv }) // Load Nuxt Config @@ -105,13 +105,17 @@ type ArgsT = Exclude< type DevProxy = Awaited> -async function _createDevProxy( - nuxtOptions: NuxtOptions, - listenOptions: Partial, -) { +async function _createDevProxy(nuxtOptions: NuxtOptions, listenOptions: Partial) { + const jiti = createJiti(nuxtOptions.rootDir) let loadingMessage = 'Nuxt dev server is starting...' - const loadingTemplate = nuxtOptions.devServer.loadingTemplate - ?? await importModule('@nuxt/ui-templates', nuxtOptions.modulesDir).then(r => r.loading) + let loadingTemplate = nuxtOptions.devServer.loadingTemplate + for (const url of nuxtOptions.modulesDir) { + // @ts-expect-error this is for backwards compatibility + if (loadingTemplate) { + break + } + loadingTemplate = await jiti.import<{ loading: () => string }>('@nuxt/ui-templates', { parentURL: url }).then(r => r.loading) + } const { createProxyServer } = await import('httpxy') const proxy = createProxyServer({}) diff --git a/src/commands/info.ts b/src/commands/info.ts index 717854847..3085742d5 100644 --- a/src/commands/info.ts +++ b/src/commands/info.ts @@ -1,19 +1,18 @@ import os from 'node:os' -import { existsSync, readFileSync } from 'node:fs' -import { createRequire } from 'node:module' import { resolve } from 'pathe' import { createJiti } from 'jiti' -import destr from 'destr' -import type { PackageJson } from 'pkg-types' +import { readPackageJSON } from 'pkg-types' import { splitByCase } from 'scule' import clipboardy from 'clipboardy' import type { NuxtConfig, NuxtModule } from '@nuxt/schema' import { defineCommand } from 'citty' import { detectPackageManager } from 'nypm' -import { getPackageManagerVersion } from '../utils/packageManagers' -import { findup } from '../utils/fs' import nuxiPkg from '../../package.json' assert { type: 'json' } + +import { tryResolveNuxt } from '../utils/kit' +import { getPackageManagerVersion } from '../utils/packageManagers' + import { cwdArgs, legacyRootDirArgs } from './_shared' export default defineCommand({ @@ -33,13 +32,24 @@ export default defineCommand({ const nuxtConfig = await getNuxtConfig(cwd) // Find nearest package.json - const { dependencies = {}, devDependencies = {} } = findPackage(cwd) + const { dependencies = {}, devDependencies = {} } = await readPackageJSON(cwd) // Utils to query a dependency version - const getDepVersion = (name: string) => - getPkg(name, cwd)?.version || dependencies[name] || devDependencies[name] + const nuxtPath = await tryResolveNuxt(cwd) + async function getDepVersion(name: string) { + for (const url of [cwd, nuxtPath]) { + if (!url) { + continue + } + const pkg = await readPackageJSON(name, { url }).catch(() => null) + if (pkg) { + return pkg.version! + } + } + return dependencies[name] || devDependencies[name] + } - function listModules(arr: NonNullable = []) { + async function listModules(arr: NonNullable = []) { const info: string[] = [] for (let m of arr) { if (Array.isArray(m)) { @@ -48,7 +58,7 @@ export default defineCommand({ const name = normalizeConfigModule(m, cwd) if (name) { const npmName = name!.split('/').splice(0, 2).join('/') // @foo/bar/baz => @foo/bar - const v = getDepVersion(npmName) + const v = await getDepVersion(npmName) info.push('`' + (v ? `${name}@${v}` : name) + '`') } } @@ -56,7 +66,7 @@ export default defineCommand({ } // Check Nuxt version - const nuxtVersion = getDepVersion('nuxt') || getDepVersion('nuxt-nightly') || getDepVersion('nuxt-edge') || getDepVersion('nuxt3') || '-' + const nuxtVersion = await getDepVersion('nuxt') || await getDepVersion('nuxt-nightly') || await getDepVersion('nuxt-edge') || await getDepVersion('nuxt3') || '-' const isLegacy = nuxtVersion.startsWith('2') const builder = !isLegacy ? nuxtConfig.builder /* latest schema */ || '-' @@ -77,14 +87,14 @@ export default defineCommand({ NodeVersion: process.version, NuxtVersion: nuxtVersion, CLIVersion: nuxiPkg.version, - NitroVersion: getDepVersion('nitropack'), + NitroVersion: await getDepVersion('nitropack'), PackageManager: packageManager ?? 'unknown', Builder: typeof builder === 'string' ? builder : 'custom', UserConfig: Object.keys(nuxtConfig) .map(key => '`' + key + '`') .join(', '), - RuntimeModules: listModules(nuxtConfig.modules), - BuildModules: listModules((nuxtConfig as any /* nuxt v2 */).buildModules || []), + RuntimeModules: await listModules(nuxtConfig.modules), + BuildModules: await listModules((nuxtConfig as any /* nuxt v2 */).buildModules || []), } console.log('Working directory:', cwd) @@ -176,40 +186,3 @@ async function getNuxtConfig(rootDir: string) { return {} } } - -function getPkg(name: string, rootDir: string) { - // Assume it is in {rootDir}/node_modules/${name}/package.json - let pkgPath = resolve(rootDir, 'node_modules', name, 'package.json') - - // Try to resolve for more accuracy - const _require = createRequire(rootDir) - try { - pkgPath = _require.resolve(name + '/package.json') - } - catch { - // console.log('not found:', name) - } - - return readJSONSync(pkgPath) as PackageJson -} - -function findPackage(rootDir: string) { - return ( - findup(rootDir, (dir) => { - const p = resolve(dir, 'package.json') - if (existsSync(p)) { - return readJSONSync(p) as PackageJson - } - }) || {} - ) -} - -function readJSONSync(filePath: string) { - try { - return destr(readFileSync(filePath, 'utf-8')) - } - catch { - // TODO: Warn error - return null - } -} diff --git a/src/commands/module/_utils.ts b/src/commands/module/_utils.ts index 06f2a8066..532919a2f 100644 --- a/src/commands/module/_utils.ts +++ b/src/commands/module/_utils.ts @@ -1,6 +1,6 @@ import { $fetch } from 'ofetch' +import { readPackageJSON } from 'pkg-types' import { satisfies, coerce } from 'semver' -import { tryRequireModule } from '../../utils/cjs' export const categories = [ 'Analytics', @@ -117,15 +117,11 @@ export function checkNuxtCompatibility( } export async function getNuxtVersion(cwd: string) { - const nuxtPkg = tryRequireModule('nuxt/package.json', cwd) + const nuxtPkg = await readPackageJSON('nuxt', { url: cwd }) if (nuxtPkg) { - return nuxtPkg.version + return nuxtPkg.version! } - const pkg = await getProjectPackage(cwd) + const pkg = await readPackageJSON(cwd) const pkgDep = pkg?.dependencies?.['nuxt'] || pkg?.devDependencies?.['nuxt'] return (pkgDep && coerce(pkgDep)?.version) || '3.0.0' } - -export async function getProjectPackage(cwd: string) { - return await tryRequireModule('./package.json', cwd) -} diff --git a/src/commands/module/add.ts b/src/commands/module/add.ts index 67b5cd5ff..038483027 100644 --- a/src/commands/module/add.ts +++ b/src/commands/module/add.ts @@ -11,13 +11,13 @@ import { $fetch } from 'ofetch' import { satisfies } from 'semver' import { updateConfig } from 'c12/update' import { colors } from 'consola/utils' +import { readPackageJSON } from 'pkg-types' import { cwdArgs, logLevelArgs } from '../_shared' import { runCommand } from '../../run' import { checkNuxtCompatibility, fetchModules, getNuxtVersion, - getProjectPackage, } from './_utils' import type { NuxtModule } from './_utils' @@ -63,7 +63,7 @@ export default defineCommand({ async setup(ctx) { const cwd = resolve(ctx.args.cwd) const modules = ctx.args._.map(e => e.trim()).filter(Boolean) - const projectPkg = await getProjectPackage(cwd) + const projectPkg = await readPackageJSON(cwd) if (!projectPkg.dependencies?.nuxt && !projectPkg.devDependencies?.nuxt) { consola.warn(`No \`nuxt\` dependency detected in \`${cwd}\`.`) diff --git a/src/commands/prepare.ts b/src/commands/prepare.ts index 05d4ad6e7..4893027bd 100644 --- a/src/commands/prepare.ts +++ b/src/commands/prepare.ts @@ -26,11 +26,7 @@ export default defineCommand({ const cwd = resolve(ctx.args.cwd || ctx.args.rootDir) - const { - loadNuxt, - buildNuxt, - writeTypes = writeTypesLegacy, - } = await loadKit(cwd) + const { loadNuxt, buildNuxt, writeTypes = writeTypesLegacy } = await loadKit(cwd) const nuxt = await loadNuxt({ cwd, dotenv: { diff --git a/src/commands/typecheck.ts b/src/commands/typecheck.ts index 604a89565..9ce031f78 100644 --- a/src/commands/typecheck.ts +++ b/src/commands/typecheck.ts @@ -1,12 +1,13 @@ +import { fileURLToPath } from 'node:url' import { execa } from 'execa' import { resolve } from 'pathe' import { defineCommand } from 'citty' import { isBun } from 'std-env' +import { createJiti } from 'jiti' // we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7` import { writeTypes as writeTypesLegacy } from '@nuxt/kit' -import { tryResolveModule } from '../utils/esm' import { loadKit } from '../utils/kit' import { cwdArgs, legacyRootDirArgs, logLevelArgs } from './_shared' @@ -26,11 +27,7 @@ export default defineCommand({ const cwd = resolve(ctx.args.cwd || ctx.args.rootDir) - const { - loadNuxt, - buildNuxt, - writeTypes = writeTypesLegacy, - } = await loadKit(cwd) + const { loadNuxt, buildNuxt, writeTypes = writeTypesLegacy } = await loadKit(cwd) const nuxt = await loadNuxt({ cwd, overrides: { @@ -44,13 +41,15 @@ export default defineCommand({ await buildNuxt(nuxt) await nuxt.close() + const jiti = createJiti(cwd) + // Prefer local install if possible const [resolvedTypeScript, resolvedVueTsc] = await Promise.all([ - tryResolveModule('typescript'), - tryResolveModule('vue-tsc/bin/vue-tsc.js'), + jiti.esmResolve('typescript', { try: true }), + jiti.esmResolve('vue-tsc/bin/vue-tsc.js', { try: true }), ]) if (resolvedTypeScript && resolvedVueTsc) { - await execa(resolvedVueTsc, ['--noEmit'], { + await execa(fileURLToPath(resolvedVueTsc), ['--noEmit'], { preferLocal: true, stdio: 'inherit', cwd, diff --git a/src/utils/banner.ts b/src/utils/banner.ts index 4fad640a6..06cde526f 100644 --- a/src/utils/banner.ts +++ b/src/utils/banner.ts @@ -1,22 +1,14 @@ import { colors } from 'consola/utils' -import { tryRequireModule } from './cjs' +import { readPackageJSON } from 'pkg-types' -export function showVersions(cwd: string) { +export async function showVersions(cwd: string) { const { bold, gray, green } = colors - const getPkgVersion = (pkg: string) => { - return tryRequireModule(`${pkg}/package.json`, cwd)?.version || '' + async function getPkgVersion(pkg: string) { + const p = await readPackageJSON(pkg, { url: cwd }) + return p?.version || '' } - const nuxtVersion - = getPkgVersion('nuxt') - || getPkgVersion('nuxt-nightly') - || getPkgVersion('nuxt3') - || getPkgVersion('nuxt-edge') - const nitroVersion - = getPkgVersion('nitropack') || getPkgVersion('nitropack-nightly') || getPkgVersion('nitropack-edge') - console.log( - gray( - green(`Nuxt ${bold(nuxtVersion)}`) - + (nitroVersion ? ` with Nitro ${bold(nitroVersion)}` : ''), - ), - ) + const nuxtVersion = await getPkgVersion('nuxt') || await getPkgVersion('nuxt-nightly') || await getPkgVersion('nuxt3') || await getPkgVersion('nuxt-edge') + const nitroVersion = await getPkgVersion('nitropack') || await getPkgVersion('nitropack-nightly') || await getPkgVersion('nitropack-edge') + + console.log(gray(green(`Nuxt ${bold(nuxtVersion)}`) + (nitroVersion ? ` with Nitro ${bold(nitroVersion)}` : ''))) } diff --git a/src/utils/cjs.ts b/src/utils/cjs.ts deleted file mode 100644 index 498ecc624..000000000 --- a/src/utils/cjs.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { createRequire } from 'node:module' -import { dirname, normalize } from 'pathe' - -export function getModulePaths(paths?: string | string[]): string[] { - return ([] as Array) - .concat( - global.__NUXT_PREPATHS__, - paths, - process.cwd(), - global.__NUXT_PATHS__, - ) - .filter(Boolean) as string[] -} - -const _require = createRequire(process.cwd()) - -export function resolveModule(id: string, paths?: string | string[]) { - return normalize(_require.resolve(id, { paths: getModulePaths(paths) })) -} - -export function requireModule(id: string, paths?: string | string[]) { - return _require(resolveModule(id, paths)) -} - -export function tryRequireModule(id: string, paths?: string | string[]) { - try { - return requireModule(id, paths) - } - catch { - return null - } -} - -export function getNearestPackage(id: string, paths?: string | string[]) { - while (dirname(id) !== id) { - try { - return requireModule(id + '/package.json', paths) - } - catch { - // Ignore error - } - id = dirname(id) - } - return null -} diff --git a/src/utils/dev.ts b/src/utils/dev.ts index 05de1679a..924fdda2d 100644 --- a/src/utils/dev.ts +++ b/src/utils/dev.ts @@ -11,10 +11,11 @@ import { joinURL } from 'ufo' import type { HTTPSOptions, ListenURL, Listener, ListenOptions } from 'listhen' import { listen } from 'listhen' import type { Nuxt, NuxtConfig } from '@nuxt/schema' +import type { Jiti } from 'jiti/lib/types' +import { createJiti } from 'jiti' import { loadKit } from '../utils/kit' import { loadNuxtManifest, writeNuxtManifest } from '../utils/nuxt' import { clearBuildDir } from '../utils/fs' -import { importModule } from './esm' export type NuxtDevIPCMessage = | { type: 'nuxt:internal:dev:ready', port: number } @@ -85,6 +86,7 @@ class NuxtDevServer extends EventEmitter { private _distWatcher?: FSWatcher private _currentNuxt?: Nuxt private _loadingMessage?: string + private _jiti: Jiti loadDebounced: (reload?: boolean, reason?: string) => void handler: RequestListener @@ -103,6 +105,8 @@ class NuxtDevServer extends EventEmitter { _initResolve() }) + this._jiti = createJiti(options.cwd) + this.handler = async (req, res) => { await _initPromise if (this._handler) { @@ -123,7 +127,7 @@ class NuxtDevServer extends EventEmitter { const loadingTemplate = this.options.loadingTemplate || this._currentNuxt?.options.devServer.loadingTemplate - || await importModule('@nuxt/ui-templates', this.options.cwd).then(r => r.loading).catch(() => {}) + || await this._jiti.import<{ loading: () => string }>('@nuxt/ui-templates').then(r => r.loading).catch(() => {}) || ((params: { loading: string }) => `

${params.loading}

`) res.end( loadingTemplate({ diff --git a/src/utils/esm.ts b/src/utils/esm.ts deleted file mode 100644 index e4efe39cf..000000000 --- a/src/utils/esm.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { pathToFileURL } from 'node:url' -import { interopDefault, resolvePath } from 'mlly' - -export async function tryResolveModule(id: string, url = import.meta.url) { - try { - return await resolvePath(id, { url }) - } - catch { - // Ignore error - } -} - -export async function importModule( - id: string, - url: string | string[] = import.meta.url, -) { - const resolvedPath = await resolvePath(id, { url }) - return import(pathToFileURL(resolvedPath).href).then(interopDefault) -} - -export function tryImportModule(id: string, url = import.meta.url) { - try { - return importModule(id, url).catch(() => undefined) - } - catch { - // Ignore error - } -} diff --git a/src/utils/fs.ts b/src/utils/fs.ts index d0dcd558f..34a411a5e 100644 --- a/src/utils/fs.ts +++ b/src/utils/fs.ts @@ -1,5 +1,5 @@ import { existsSync, promises as fsp } from 'node:fs' -import { dirname, join } from 'pathe' +import { join } from 'pathe' import { consola } from 'consola' // Check if a file exists @@ -53,18 +53,3 @@ export async function touchFile(path: string) { consola.error(`Failed to create file: ${path}`) }) } - -export function findup( - rootDir: string, - fn: (dir: string) => T | undefined, -): T | null { - let dir = rootDir - while (dir !== dirname(dir)) { - const res = fn(dir) - if (res) { - return res - } - dir = dirname(dir) - } - return null -} diff --git a/src/utils/kit.ts b/src/utils/kit.ts index d9ac3ad40..f87ea0bd4 100644 --- a/src/utils/kit.ts +++ b/src/utils/kit.ts @@ -1,19 +1,15 @@ // we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7` import { writeTypes as writeTypesLegacy } from '@nuxt/kit' -import { importModule, tryResolveModule } from './esm' +import { createJiti } from 'jiti' -export const loadKit = async ( - rootDir: string, -): Promise => { +export const loadKit = async (rootDir: string): Promise => { + const jiti = createJiti(rootDir) try { // Without PNP (or if users have a local install of kit, we bypass resolving from Nuxt) - const localKit = await tryResolveModule('@nuxt/kit', rootDir) + const localKit = jiti.esmResolve('@nuxt/kit', { try: true }) // Otherwise, we resolve Nuxt _first_ as it is Nuxt's kit dependency that will be used const rootURL = localKit ? rootDir : (await tryResolveNuxt(rootDir)) || rootDir - let kit: typeof import('@nuxt/kit') = await importModule( - '@nuxt/kit', - rootURL, - ) + let kit: typeof import('@nuxt/kit') = await jiti.import('@nuxt/kit', { parentURL: rootURL }) if (!kit.writeTypes) { // Polyfills for schema < 3.7 kit = { ...kit, writeTypes: writeTypesLegacy } @@ -30,9 +26,10 @@ export const loadKit = async ( } } -async function tryResolveNuxt(rootDir: string) { - for (const pkg of ['nuxt-nightly', 'nuxt3', 'nuxt', 'nuxt-edge']) { - const path = await tryResolveModule(pkg, rootDir) +export async function tryResolveNuxt(rootDir: string) { + const jiti = createJiti(rootDir) + for (const pkg of ['nuxt-nightly', 'nuxt', 'nuxt3', 'nuxt-edge']) { + const path = jiti.esmResolve(pkg, { try: true }) if (path) { return path } diff --git a/types.d.ts b/types.d.ts index b84f72db7..db2307f00 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,8 +1,6 @@ /* eslint-disable no-var */ declare global { - var __NUXT_PREPATHS__: undefined | string[] - var __NUXT_PATHS__: undefined | string[] var __nuxt_cli__: | undefined | {