Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions playground/plugins/memleak.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineNuxtPlugin, ref } from '#imports'

ref('memory-leak-warning-shown')

export default defineNuxtPlugin(() => {
// Show memory leak warning
})
10 changes: 9 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineNuxtModule, addPlugin, createResolver, addBuildPlugin, addComponent, addServerPlugin } from '@nuxt/kit'
import { defineNuxtModule, addPlugin, createResolver, addBuildPlugin, addComponent, addServerPlugin, addImports } from '@nuxt/kit'
import { setupDevToolsUI } from './devtools'
import { InjectHydrationPlugin } from './plugins/hydration'

Expand Down Expand Up @@ -38,6 +38,14 @@ export default defineNuxtModule<ModuleOptions>({
addPlugin(resolver.resolve('./runtime/plugins/third-party-scripts/plugin.client'))
addServerPlugin(resolver.resolve('./runtime/plugins/third-party-scripts/nitro.plugin'))

// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
])
Comment on lines +56 to +62
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the actual file paths for vue composables

echo "=== Searching for vue.ts composables file in src/runtime ==="
fd -t f 'vue.ts' src/runtime

echo -e "\n=== Checking if ./runtime/composables/vue.ts exists ==="
ls -la src/runtime/composables/vue.ts 2>/dev/null || echo "File NOT found at src/runtime/composables/vue.ts"

echo -e "\n=== Checking if ./runtime/core/composables/vue.ts exists ==="
ls -la src/runtime/core/composables/vue.ts 2>/dev/null || echo "File NOT found at src/runtime/core/composables/vue.ts"

echo -e "\n=== Listing all files in src/runtime ==="
find src/runtime -type f -name '*.ts' | head -20

Repository: nuxt/hints

Length of output: 1037


Path mismatch: resolver path doesn't match actual file location.

The addImports call references './runtime/composables/vue', but the actual implementation is at src/runtime/core/composables/vue.ts. The path is missing the core/ segment, which will cause the imports to fail at runtime.

πŸ› Proposed fix for path
     // Imports for server side misusage detection
     addImports([
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'ref' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowRef' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'reactive' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowReactive' },
     ])
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
])
// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowReactive' },
])
πŸ€– Prompt for AI Agents
In `@src/module.ts` around lines 56 - 62, The import paths used in the addImports
call are incorrect: locate the addImports([...]) block (the entries adding
'ref', 'shallowRef', 'reactive', 'shallowReactive') and update each
resolver.resolve call to include the missing core segment in the module path
(i.e., change "./runtime/composables/vue" to "./runtime/core/composables/vue")
so resolver.resolve points to the actual implementation; keep the same import
names and structure.


nuxt.hook('prepare:types', ({ references }) => {
references.push({
types: resolver.resolve('./runtime/types.d.ts'),
Expand Down
19 changes: 19 additions & 0 deletions src/runtime/composables/vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ref as _ref, reactive as _reactive, shallowReactive as _shallowReactive, shallowRef as _shallowRef, getCurrentInstance } from 'vue'
import { tryUseNuxtApp } from '#app'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function wrapWithWarning<Fn extends (...args: any[]) => any>(fn: Fn, name: string): Fn {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return function (this: unknown, ...args: any[]) {
const nuxtApp = tryUseNuxtApp()
if (!nuxtApp && !getCurrentInstance()) {
console.error(new Error(`[@nuxt/hints] ${name}() called outside of setup() or without Nuxt app context. This may lead to Server side memory leaks.`))
}
return fn.call(this, ...args)
} as Fn
}

export const ref = import.meta.server ? wrapWithWarning(_ref, 'ref') : _ref
export const reactive = import.meta.server ? wrapWithWarning(_reactive, 'reactive') : _reactive
export const shallowReactive = import.meta.server ? wrapWithWarning(_shallowReactive, 'shallowReactive') : _shallowReactive
export const shallowRef = import.meta.server ? wrapWithWarning(_shallowRef, 'shallowRef') : _shallowRef
Loading