vuejs/core · error · Error

[vue/compiler-sfc] globalTypeFiles requires fs access.

Error message

[vue/compiler-sfc] globalTypeFiles requires fs access.

What it means

Thrown by resolveGlobalScope in @vue/compiler-sfc's type-resolver when options.globalTypeFiles is set but no filesystem is available. Reading global .ts type files requires Node fs (or an injected fs), and resolveFS(ctx) returned undefined. The guard at resolveType.ts:879 fails fast rather than silently dropping global types.

Source

Thrown at packages/compiler-sfc/src/script/resolveType.ts:879

    return qualifiedNameToPath(ref)
  } else {
    return 'default'
  }
}

function qualifiedNameToPath(node: Identifier | TSQualifiedName): string[] {
  if (node.type === 'Identifier') {
    return [node.name]
  } else {
    return [...qualifiedNameToPath(node.left), node.right.name]
  }
}

function resolveGlobalScope(ctx: TypeResolveContext): TypeScope[] | undefined {
  if (ctx.options.globalTypeFiles) {
    const fs = resolveFS(ctx)
    if (!fs) {
      throw new Error('[vue/compiler-sfc] globalTypeFiles requires fs access.')
    }
    return ctx.options.globalTypeFiles.map(file =>
      fileToScope(ctx, normalizePath(file), true),
    )
  }
}

let ts: typeof TS | undefined
let loadTS: (() => typeof TS) | undefined

/**
 * @private
 */
export function registerTS(_loadTS: () => typeof TS): void {
  loadTS = () => {
    try {
      return _loadTS()
    } catch (err: any) {

View on GitHub (pinned to a2b40db9a8)

Solutions

  1. Provide an fs implementation via SFCScriptCompileOptions.fs (a custom or memfs-backed fs) before using globalTypeFiles.
  2. Ensure TypeScript is registered with registerTS so that ts.sys can serve as the filesystem fallback (resolveFS uses ctx.options.fs || ts?.sys).
  3. Remove globalTypeFiles from options when running in an environment without fs access; rely on per-file type imports instead.

Example fix

// before
compileScript(sfc, { id, globalTypeFiles: ['./types/shims.d.ts'] })

// after — supply an fs (here, Node's fs)
import * as nodeFs from 'fs'
compileScript(sfc, {
  id,
  globalTypeFiles: ['./types/shims.d.ts'],
  fs: nodeFs,
})
Defensive patterns

Strategy: validation

Validate before calling

// Provide an fs whenever you set globalTypeFiles.
import * as nodeFs from 'fs'
function safeCompileScript(sfc, opts) {
  if (opts.globalTypeFiles && !opts.fs) {
    opts = { ...opts, fs: nodeFs }
  }
  return compileScript(sfc, opts)
}

Type guard

function hasFs(opts: unknown): boolean {
  return !!opts && typeof (opts as any).fs === 'object' && typeof (opts as any).fs?.readFile === 'function'
}

Prevention

When it happens

Trigger: Calling compileScript with globalTypeFiles populated from an environment where neither ctx.fs nor options.fs nor ts.sys provides a filesystem (e.g. a pure browser or constrained runtime); forgetting to register TypeScript via registerTS before relying on globalTypeFiles.

Common situations: Using globalTypeFiles (a relatively new feature for shared global TS type context) in a browser build or a sandboxed bundler; downgrading TypeScript availability at runtime; misconfiguring a custom fs option.

Related errors


AI-assisted analysis of vuejs/core@a2b40db9a8 (2026-08-12). Data as JSON: /api/errors/2b0d33afb20427d3. Report an issue: GitHub.