ronantakizawa/codereview-bench huggingface dataset:
Repository: nuxt/nuxt
File: packages/kit/src/ignore.ts (TypeScript)

Code before:
import { existsSync, readFileSync } from 'node:fs'
import ignore from 'ignore'
import { join, relative, resolve } from 'pathe'
import { tryUseNuxt, useNuxt } from './context'

const checkIgnoreOutdated = (nuxt = useNuxt()) => !nuxt._ignorePatterns?.join(',').startsWith(nuxt.options.ignore.flatMap(resolveGroupSyntax).join(','))

/**
 * Return a filter function to filter an array of paths
 */
export function isIgnored (pathname: string): boolean {
  const nuxt = tryUseNuxt()

  // Happens with CLI reloads
  if (!nuxt) {
    return false
  }

  if (!nuxt._ignore || checkIgnoreOutdated(nuxt)) {
    nuxt._ignore = ignore(nuxt.options.ignoreOptions)
    nuxt._ignore.add(resolveIgnorePatterns())
  }

  const cwds = nuxt.options._layers?.map(layer => layer.cwd).sort((a, b) => b.length - a.length)
  const layer = cwds?.find(cwd => pathname.startsWith(cwd))
  const relativePath = relative(layer ?? nuxt.options.rootDir, pathname)
  if (relativePath[0] === '.' && relativePath[1] === '.') {
    return false
  }
  return !!(relativePath && nuxt._ignore.ignores(relativePath))
}

Review comment (performance):
I think we need a more performant check as `isIgnored` will be called _lots_ of times - once for every single file that globby or chokidar scans.

Some kind of cached outdated check, perhaps, that doesn't need to resolve the patterns?

Code after:
import { existsSync, readFileSync } from 'node:fs'
import ignore from 'ignore'
import { join, relative, resolve } from 'pathe'
import { tryUseNuxt } from './context'

/**
 * Return a filter function to filter an array of paths
 */
export function isIgnored (pathname: string): boolean {
  const nuxt = tryUseNuxt()

  // Happens with CLI reloads
  if (!nuxt) {
    return false
  }

  if (!nuxt._ignore) {
    nuxt._ignore = ignore(nuxt.options.ignoreOptions)
    nuxt._ignore.add(resolveIgnorePatterns())
  }

  const cwds = nuxt.options._layers?.map(layer => layer.cwd).sort((a, b) => b.length - a.length)
  const layer = cwds?.find(cwd => pathname.startsWith(cwd))
  const relativePath = relative(layer ?? nuxt.options.rootDir, pathname)
  if (relativePath[0] === '.' && relativePath[1] === '.') {
    return false
  }
  return !!(relativePath && nuxt._ignore.ignores(relativePath))
}

const NEGATION_RE = /^(!?)(.*)$/
Repository: nuxt/nuxt
File: packages/nuxt/src/head/module.ts (TypeScript)

Code before:

    // Opt-out feature allowing dependencies using @vueuse/head to work
    const unheadVue = await tryResolveModule('@unhead/vue', nuxt.options.modulesDir) || '@unhead/vue'
    if (nuxt.options.experimental.polyfillVueUseHead) {
      // backwards compatibility
      nuxt.options.alias['@vueuse/head'] = unheadVue
      addPlugin({ src: resolve(runtimeDir, 'plugins/vueuse-head-polyfill') })
    }

    addTemplate({
      filename: 'unhead-plugins.mjs',
      getContents () {
        if (!nuxt.options.experimental.headNext) {
          return 'export default []'
        }
        return `import { CapoPlugin } from ${JSON.stringify(unheadVue)};
export default import.meta.server ? [CapoPlugin({ track: true })] : [];`
      },
    })

    addTemplate({
      filename: 'unhead.config.mjs',
      getContents (ctx) {
        const renderSSRHeadOptions = defu(options.renderSSRHeadOptions, {
          omitLineBreaks: !(ctx.nuxt.options.dev || ctx.nuxt.options.test),
        })

        return [
          `export const renderSSRHeadOptions = ${JSON.stringify(renderSSRHeadOptions)}`,
        ].join('\n')
      },
    })

    // template is only exposed in nuxt context, expose in nitro context as well
    nuxt.hooks.hook('nitro:config', (config) => {
      config.virtual!['#internal/unhead-plugins.mjs'] = () => nuxt.vfs['#build/unhead-plugins']
      config.virtual!['#internal/unhead.config.mjs'] = () => nuxt.vfs['#build/unhead.config']
    })

    // Add library-specific plugin
    addPlugin({ src: resolve(runtimeDir, 'plugins/unhead') })
  },
})


Review comment (suggestion):
I think this can be moved up into `defaults` function above `setup` and it will be pre-merged for us...

Code after:
      addPlugin({ src: resolve(runtimeDir, 'plugins/vueuse-head-polyfill') })
    }

    addTemplate({
      filename: 'unhead-plugins.mjs',
      getContents () {
        if (!nuxt.options.experimental.headNext) {
          return 'export default []'
        }
        return `import { CapoPlugin } from ${JSON.stringify(unheadVue)};
export default import.meta.server ? [CapoPlugin({ track: true })] : [];`
      },
    })

    addTemplate({
      filename: 'unhead.config.mjs',
      getContents () {
        return [
          `export const renderSSRHeadOptions = ${JSON.stringify(options.renderSSRHeadOptions || {})}`,
        ].join('\n')
      },
    })

    // template is only exposed in nuxt context, expose in nitro context as well
    nuxt.hooks.hook('nitro:config', (config) => {
      config.virtual!['#internal/unhead-plugins.mjs'] = () => nuxt.vfs['#build/unhead-plugins']
      config.virtual!['#internal/unhead.config.mjs'] = () => nuxt.vfs['#build/unhead.config']
    })

    // Add library-specific plugin
    addPlugin({ src: resolve(runtimeDir, 'plugins/unhead') })
  },
})
Repository: nuxt/nuxt
File: packages/nuxt/src/app/plugins/chunk-reload-immediate.client.ts (TypeScript)

Code before:
import { defineNuxtPlugin } from '../nuxt'
import { reloadNuxtApp } from '../composables/chunk'

const reloadNuxtApp_ = () => { reloadNuxtApp({ persistState: true }) }

// See https://github.com/nuxt/nuxt/issues/23612 for more context
export default defineNuxtPlugin({
  name: 'nuxt:chunk-reload-immediate',
  setup (nuxtApp) {
    // Reload when a `chunkError` is thrown
    nuxtApp.hook('app:chunkError', reloadNuxtApp_)

    // Reload when the app manifest updates
    nuxtApp.hook('app:manifest:update', reloadNuxtApp_)
  },
})


Review comment (suggestion):
If we are reloading while navigating, we should probably reload at the new path rather than the current one.

Code after:
import { defineNuxtPlugin } from '../nuxt'
import { reloadNuxtApp } from '../composables/chunk'
import { addRouteMiddleware } from '../composables/router'

const reloadNuxtApp_ = (path: string) => { reloadNuxtApp({ persistState: true, path }) }

// See https://github.com/nuxt/nuxt/issues/23612 for more context
export default defineNuxtPlugin({
  name: 'nuxt:chunk-reload-immediate',
  setup (nuxtApp) {
    // Remember `to.path` when navigating to a new path: A `chunkError` may occur during navigation, we then want to then reload at `to.path`
    let currentlyNavigationTo: null | string = null
    addRouteMiddleware((to) => {
      currentlyNavigationTo = to.path
    })

    // Reload when a `chunkError` is thrown
    nuxtApp.hook('app:chunkError', () => reloadNuxtApp_(currentlyNavigationTo ?? nuxtApp._route.path))

    // Reload when the app manifest updates
    nuxtApp.hook('app:manifest:update', () => reloadNuxtApp_(nuxtApp._route.path))
  },
})
Repository: nuxt/nuxt
File: packages/nuxt/src/components/runtime/client-component.ts (TypeScript)

Code before:
import { defineAsyncComponent, defineComponent, h } from 'vue'
import type { AsyncComponentLoader } from 'vue'
import ClientOnly from '#app/components/client-only'
import { useNuxtApp } from '#app'

/* @__NO_SIDE_EFFECTS__ */
export const createClientPage = (loader: AsyncComponentLoader) => {
  const page = defineAsyncComponent(import.meta.dev
    ? () => loader().then((m) => {
        // mark component as client-only for `definePageMeta`
        (m.default || m).__clientOnlyPage = true
        return m.default || m
      })
    : loader)

  return defineComponent({
    inheritAttrs: false,
    setup (_, { attrs }) {
      const nuxtApp = useNuxtApp()
      if (import.meta.server || nuxtApp.isHydrating) {
        return () => h('div', [
          h(ClientOnly, undefined, {
            default: () => h(page, attrs),
          }),
        ])
      }
      return () => h(page, attrs)
    },
  })

Review comment (suggestion):
avoiding barrel file imports can help with vite dev server speed

```suggestion
import { useNuxtApp } from '#app/nuxt'
```

Code after:
import { defineAsyncComponent, defineComponent, h } from 'vue'
import type { AsyncComponentLoader } from 'vue'
import ClientOnly from '#app/components/client-only'
import { useNuxtApp } from '#app/nuxt'

/* @__NO_SIDE_EFFECTS__ */
export const createClientPage = (loader: AsyncComponentLoader) => {
  const page = defineAsyncComponent(import.meta.dev
    ? () => loader().then((m) => {
        // mark component as client-only for `definePageMeta`
        (m.default || m).__clientOnlyPage = true
        return m.default || m
      })
    : loader)

  return defineComponent({
    inheritAttrs: false,
    setup (_, { attrs }) {
      const nuxtApp = useNuxtApp()
      if (import.meta.server || nuxtApp.isHydrating) {
        return () => h('div', [
          h(ClientOnly, undefined, {
            default: () => h(page, attrs),
          }),
        ])
      }
      return () => h(page, attrs)
    },
  })
Repository: nuxt/nuxt
File: packages/kit/src/context.ts (TypeScript)

Code before:
    if (fallbackInstance) {
      logger.warn('Using fallback global Nuxt instance. You may be using a @nuxt/kit composable outside of a Nuxt context, this behavior is deprecated and will be removed in v4.')
      return fallbackInstance
    }

    throw new Error('Nuxt instance is unavailable!')
  }
  return instance
}

/**
 * Get access to Nuxt instance.
 *
 * Returns null if Nuxt instance is unavailable.
 * @example
 * ```js
 * const nuxt = tryUseNuxt()
 * if (nuxt) {
 *  // Do something
 * }
 * ```
 */
export function tryUseNuxt (): Nuxt | null {
  const nuxt = nuxtCtx().tryUse()
  if (!nuxt) {
    logger.warn('Using fallback global Nuxt instance. You may be using a @nuxt/kit composable outside of a Nuxt context, this behavior is deprecated and will be removed in v4.')
    return fallbackNuxtCtx.tryUse()
  }
  return nuxt
}


Review comment (suggestion):
I'm not sure how to rephrase this to make it sound a bit gentler 😅. Any suggestions?

cc @danielroe 

Code after:
 * Throws an error if Nuxt instance is unavailable.
 * @example
 * ```js
 * const nuxt = useNuxt()
 * ```
 */
export function useNuxt (): Nuxt {
  const instance = asyncNuxtStorage.tryUse() || nuxtCtx.tryUse()
  if (!instance) {
    throw new Error('Nuxt instance is unavailable!')
  }
  return instance
}

/**
 * Get access to Nuxt instance.
 *
 * Returns null if Nuxt instance is unavailable.
 * @example
 * ```js
 * const nuxt = tryUseNuxt()
 * if (nuxt) {
 *  // Do something
 * }
 * ```
 */
export function tryUseNuxt (): Nuxt | null {
  return asyncNuxtStorage.tryUse() || nuxtCtx.tryUse()
}

export function runWithNuxtContext<T extends (...args: any[]) => any> (nuxt: Nuxt, fn: T) {
  return asyncNuxtStorage.call(nuxt, fn) as ReturnType<T>
}
Repository: nuxt/nuxt
File: packages/vite/src/vite-node.ts (TypeScript)

Code before:

function createViteNodeApp (ctx: ViteBuildContext, invalidates: Set<string> = new Set()) {
  const app = createApp()

  app.use('/manifest', defineEventHandler(() => {
    const manifest = getManifest(ctx)
    return manifest
  }))

  app.use('/invalidates', defineEventHandler(() => {
    const ids = Array.from(invalidates)
    invalidates.clear()
    return ids
  }))

  app.use('/module', defineLazyEventHandler(() => {
    const viteServer = ctx.ssrServer!
    const node = new ViteNodeServer(viteServer, {
      deps: {
        inline: [
          /^virtual:/,
          /\.ts$/,
          // Rollup
          /\0/,
          // Common
          /^#/,
          /\?/,
        ],
        external: [
          '#shared',
          new RegExp('^' + escapeStringRegexp(withTrailingSlash(resolve(ctx.nuxt.options.rootDir, ctx.nuxt.options.dir.shared)))),
        ],
      },
      transformMode: {
        ssr: [/.*/],
        web: [],
      },
    })

    return eventHandler(async (event) => {
      const moduleId = decodeURI(event.path).substring(1)
      if (moduleId === '/') {
        throw createError({ statusCode: 400 })
      }
      if (isAbsolute(moduleId) && !isFileServingAllowed(moduleId, viteServer)) {
        throw createError({ statusCode: 403 /* Restricted */ })
      }
      const module = await node.fetchModule(moduleId).catch(async (err) => {
        const errorData = {
          code: 'VITE_ERROR',
          id: moduleId,

Review comment (suggestion):
@antfu do you think we need to pass these explicitly, or will `vite-node` already treat these as inline patterns? In my testing, it seemed to....

Code after:

function createViteNodeApp (ctx: ViteBuildContext, invalidates: Set<string> = new Set()) {
  const app = createApp()

  app.use('/manifest', defineEventHandler(() => {
    const manifest = getManifest(ctx)
    return manifest
  }))

  app.use('/invalidates', defineEventHandler(() => {
    const ids = Array.from(invalidates)
    invalidates.clear()
    return ids
  }))

  app.use('/module', defineLazyEventHandler(() => {
    const viteServer = ctx.ssrServer!
    const node = new ViteNodeServer(viteServer, {
      deps: {
        inline: [
          // Common
          /^#/,
          /\?/,
        ],
        external: [
          '#shared',
          new RegExp('^' + escapeStringRegexp(withTrailingSlash(resolve(ctx.nuxt.options.rootDir, ctx.nuxt.options.dir.shared)))),
        ],
      },
      transformMode: {
        ssr: [/.*/],
        web: [],
      },
    })

    return eventHandler(async (event) => {
      const moduleId = decodeURI(event.path).substring(1)
      if (moduleId === '/') {
        throw createError({ statusCode: 400 })
      }
      if (isAbsolute(moduleId) && !isFileServingAllowed(moduleId, viteServer)) {
        throw createError({ statusCode: 403 /* Restricted */ })
      }
      const module = await node.fetchModule(moduleId).catch(async (err) => {
        const errorData = {
          code: 'VITE_ERROR',
          id: moduleId,
          stack: '',
          ...err,
        }
Repository: nuxt/nuxt
File: packages/nuxt/src/app/config.ts (TypeScript)

Code before:
    }
  }
}

function deepAssign (obj: any, newObj: any) {
  for (const key in newObj) {
    const val = newObj[key]
    if (isPojoOrArray(val)) {
      const defaultVal = Array.isArray(val) ? [] : {}
      obj[key] = obj[key] || defaultVal
      deepAssign(obj[key], val)
    } else {
      obj[key] = val
    }
  }
}

export function useAppConfig (): AppConfig {
  const nuxtApp = useNuxtApp()
  if (!nuxtApp._appConfig) {
    nuxtApp._appConfig = (import.meta.server ? klona(__appConfig) : reactive(__appConfig)) as AppConfig
  }
  return nuxtApp._appConfig
}

export function replaceAppConfig (newConfig: AppConfig) {
  const appConfig = useAppConfig()

  deepAssign(appConfig, newConfig)
  deepDelete(appConfig, newConfig)
}

/**
 * Deep assign the current appConfig with the new one.
 *
 * Will preserve existing properties.
 */
export function updateAppConfig (appConfig: DeepPartial<AppConfig>) {
  const _appConfig = useAppConfig()
  deepAssign(_appConfig, appConfig)
}

// HMR Support
if (import.meta.dev) {
  const applyHMR = (newConfig: AppConfig) => {
    const appConfig = useAppConfig()
    if (newConfig && appConfig) {
      deepAssign(appConfig, newConfig)
      deepDelete(appConfig, newConfig)
    }
  }

Review comment (suggestion):
```suggestion
export function _replaceAppConfig (newConfig: AppConfig) {
```


Code after:
    }
  }
}

function deepAssign (obj: any, newObj: any) {
  for (const key in newObj) {
    const val = newObj[key]
    if (isPojoOrArray(val)) {
      const defaultVal = Array.isArray(val) ? [] : {}
      obj[key] = obj[key] || defaultVal
      deepAssign(obj[key], val)
    } else {
      obj[key] = val
    }
  }
}

export function useAppConfig (): AppConfig {
  const nuxtApp = useNuxtApp()
  if (!nuxtApp._appConfig) {
    nuxtApp._appConfig = (import.meta.server ? klona(__appConfig) : reactive(__appConfig)) as AppConfig
  }
  return nuxtApp._appConfig
}

export function _replaceAppConfig (newConfig: AppConfig) {
  const appConfig = useAppConfig()

  deepAssign(appConfig, newConfig)
  deepDelete(appConfig, newConfig)
}

/**
 * Deep assign the current appConfig with the new one.
 *
 * Will preserve existing properties.
 */
export function updateAppConfig (appConfig: DeepPartial<AppConfig>) {
  const _appConfig = useAppConfig()
  deepAssign(_appConfig, appConfig)
}

// HMR Support
if (import.meta.dev) {
  const applyHMR = (newConfig: AppConfig) => {
    const appConfig = useAppConfig()
    if (newConfig && appConfig) {
      deepAssign(appConfig, newConfig)
      deepDelete(appConfig, newConfig)
    }
  }
Repository: nuxt/nuxt
File: packages/nuxt/src/core/templates.ts (TypeScript)

Code before:
              : Exclude<Custom[K], undefined>
            : Exclude<Custom[K], undefined>
    : Resolved[K]
}

declare module 'nuxt/schema' {
  interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
declare module '@nuxt/schema' {
  interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
`
  },
}

export const appConfigTemplate: NuxtTemplate = {
  filename: 'app.config.mjs',
  write: true,
  getContents ({ app, nuxt }) {
    return `
import { defuFn } from 'defu'

const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)}

/** client **/
import { replaceAppConfig } from '#app/config'

// Vite - webpack is handled directly in #app/config
if (import.meta.dev && !import.meta.nitro && import.meta.hot) {
  import.meta.hot.accept((newModule) => {
    replaceAppConfig(newModule.default)
  })
}
/** client-end **/

${app.configs.map((id: string, index: number) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join('\n')}

export default /*@__PURE__*/ defuFn(${app.configs.map((_id: string, index: number) => `cfg${index}`).concat(['inlineConfig']).join(', ')})
`
  },
}

export const publicPathTemplate: NuxtTemplate = {
  filename: 'paths.mjs',
  getContents ({ nuxt }) {
    return [
      'import { joinRelativeURL } from \'ufo\'',
      !nuxt.options.dev && 'import { useRuntimeConfig } from \'nitro/runtime\'',

      nuxt.options.dev
        ? `const appConfig = ${JSON.stringify(nuxt.options.app)}`

Review comment (suggestion):
```suggestion
import { _replaceAppConfig } from '#app/config'
```


Code after:
              : Exclude<Custom[K], undefined>
            : Exclude<Custom[K], undefined>
    : Resolved[K]
}

declare module 'nuxt/schema' {
  interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
declare module '@nuxt/schema' {
  interface AppConfig extends MergedAppConfig<ResolvedAppConfig, CustomAppConfig> { }
}
`
  },
}

export const appConfigTemplate: NuxtTemplate = {
  filename: 'app.config.mjs',
  write: true,
  getContents ({ app, nuxt }) {
    return `
import { defuFn } from 'defu'

const inlineConfig = ${JSON.stringify(nuxt.options.appConfig, null, 2)}

/** client **/
import { _replaceAppConfig } from '#app/config'

// Vite - webpack is handled directly in #app/config
if (import.meta.dev && !import.meta.nitro && import.meta.hot) {
  import.meta.hot.accept((newModule) => {
    _replaceAppConfig(newModule.default)
  })
}
/** client-end **/

${app.configs.map((id: string, index: number) => `import ${`cfg${index}`} from ${JSON.stringify(id)}`).join('\n')}

export default /*@__PURE__*/ defuFn(${app.configs.map((_id: string, index: number) => `cfg${index}`).concat(['inlineConfig']).join(', ')})
`
  },
}

export const publicPathTemplate: NuxtTemplate = {
  filename: 'paths.mjs',
  getContents ({ nuxt }) {
    return [
      'import { joinRelativeURL } from \'ufo\'',
      !nuxt.options.dev && 'import { useRuntimeConfig } from \'nitro/runtime\'',

      nuxt.options.dev
        ? `const appConfig = ${JSON.stringify(nuxt.options.app)}`
Repository: nuxt/nuxt
File: packages/kit/src/internal/esm.ts (TypeScript)

Code before:
import { fileURLToPath, pathToFileURL } from 'node:url'
import { interopDefault, resolvePath, resolvePathSync } from 'mlly'
import { createJiti } from 'jiti'
import { captureStackTrace } from 'errx'
import { join } from 'pathe'

export interface ResolveModuleOptions {
  /** @deprecated use `url` with URLs pointing at a file - never a directory */
  paths?: string | string[]
  url?: URL | URL[]
}

export function directoryToParentURL (dir: string): URL {
  return pathToFileURL(join(dir, '_index.js'))
}

/**
 * Resolve a module from a given root path using an algorithm patterned on
 * the upcoming `import.meta.resolve`. It returns a file URL
 *
 * @internal
 */
export async function tryResolveModule (id: string, url: URL | URL[]): Promise<string | undefined>
/** @deprecated pass URLs pointing at files */
export async function tryResolveModule (id: string, url: string | string[]): Promise<string | undefined>
export async function tryResolveModule (id: string, url: string | string[] | URL | URL[] = import.meta.url) {
  try {
    return await resolvePath(id, { url })
  } catch {
    // intentionally empty as this is a `try-` function
  }
}

export function resolveModule (id: string, options?: ResolveModuleOptions) {
  return resolvePathSync(id, { url: options?.url ?? options?.paths ?? [import.meta.url] })
}

export interface ImportModuleOptions extends ResolveModuleOptions {
  /** Automatically de-default the result of requiring the module. */

Review comment (suggestion):
```suggestion
  return pathToFileURL(dir + '/')
```


Code after:
import { fileURLToPath, pathToFileURL } from 'node:url'
import { interopDefault, resolvePath, resolvePathSync } from 'mlly'
import { createJiti } from 'jiti'
import { captureStackTrace } from 'errx'

export interface ResolveModuleOptions {
  /** @deprecated use `url` with URLs pointing at a file - never a directory */
  paths?: string | string[]
  url?: URL | URL[]
}

export function directoryToURL (dir: string): URL {
  return pathToFileURL(dir + '/')
}

/**
 * Resolve a module from a given root path using an algorithm patterned on
 * the upcoming `import.meta.resolve`. It returns a file URL
 *
 * @internal
 */
export async function tryResolveModule (id: string, url: URL | URL[]): Promise<string | undefined>
/** @deprecated pass URLs pointing at files */
export async function tryResolveModule (id: string, url: string | string[]): Promise<string | undefined>
export async function tryResolveModule (id: string, url: string | string[] | URL | URL[] = import.meta.url) {
  try {
    return await resolvePath(id, { url })
  } catch {
    // intentionally empty as this is a `try-` function
  }
}

export function resolveModule (id: string, options?: ResolveModuleOptions) {
  return resolvePathSync(id, { url: options?.url ?? options?.paths ?? [import.meta.url] })
}

export interface ImportModuleOptions extends ResolveModuleOptions {
  /** Automatically de-default the result of requiring the module. */
  interopDefault?: boolean