{"id":"05baa4b0e3052cca","repo":"vitejs/vite","slug":"module-runner-import-meta-glob-is-statically-r","errorCode":null,"errorMessage":"[module runner] \"import.meta.glob\" is statically replaced during file transformation. Make sure to reference it by the full name.","messagePattern":"\\[module runner\\] \"import\\.meta\\.glob\" is statically replaced during file transformation\\. Make sure to reference it by the full name\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/module-runner/createImportMeta.ts","lineNumber":30,"sourceCode":"})\n\nexport function createDefaultImportMeta(\n  modulePath: string,\n): ModuleRunnerImportMeta {\n  const href = posixPathToFileHref(modulePath)\n  const filename = modulePath\n  const dirname = posixDirname(modulePath)\n  return {\n    filename: isWindows ? toWindowsPath(filename) : filename,\n    dirname: isWindows ? toWindowsPath(dirname) : dirname,\n    url: href,\n    env: envProxy,\n    resolve(_id: string, _parent?: string) {\n      throw new Error('[module runner] \"import.meta.resolve\" is not supported.')\n    },\n    // should be replaced during transformation\n    glob() {\n      throw new Error(\n        `[module runner] \"import.meta.glob\" is statically replaced during ` +\n          `file transformation. Make sure to reference it by the full name.`,\n      )\n    },\n  }\n}\n\n/**\n * Create import.meta object for Node.js.\n */\nexport function createNodeImportMeta(\n  modulePath: string,\n): ModuleRunnerImportMeta {\n  const defaultMeta = createDefaultImportMeta(modulePath)\n  const href = defaultMeta.url\n\n  const importMetaResolver = createImportMetaResolver()\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/module-runner/createImportMeta.ts#L12-L48","documentation":"Thrown by the default import.meta.glob() stub in the module runner. import.meta.glob is a Vite-specific feature that is statically transformed during the build/transform phase into actual import statements. If the call reaches the module runner at runtime, it means the source file was not processed by Vite's transform pipeline (which would have replaced import.meta.glob with concrete code). This typically indicates the file bypassed transformation.","triggerScenarios":"A module is loaded by the runner without going through Vite's transform pipeline — e.g., a raw file read, a file served from node_modules without transform, or a misconfigured transport that fetches un-transformed source. Also possible if import.meta.glob is accessed via a computed/dynamic property name that the transformer can't statically detect.","commonSituations":"SSR code that imports a file from node_modules that itself uses import.meta.glob (the dependency wasn't transformed). A custom module runner transport that doesn't invoke the Vite dev server's transform. Using import.meta.glob through an alias or re-export that obscures it from static analysis.","solutions":["Ensure all modules loaded by the runner go through Vite's transform pipeline (the transport should fetchModule via the Vite dev server, not read files directly).","If a dependency uses import.meta.glob, either transform it (add to optimizeDeps.include or ssr.noExternal) or avoid importing it in SSR.","Make sure you reference import.meta.glob by its full literal name, not through a dynamic property or alias.","Check that your transport implementation calls the server's fetchModule with the correct URL."],"exampleFix":"// before — dependency uses import.meta.glob, loaded raw in SSR\n// (dependency code)\nconst mods = import.meta.glob('./*.ts')\n// after — add the dependency to ssr.noExternal so Vite transforms it\n// vite.config.ts\nssr: { noExternal: ['problematic-dep'] }","handlingStrategy":"validation","validationCode":"// Ensure the dependency is transformed before loading in SSR\nfunction ensureTransformed(dep, config) {\n  const noExternal = config.ssr?.noExternal ?? []\n  if (!noExternal.includes(dep) && !noExternal.includes(/.*/)) {\n    console.warn(`${dep} may not be transformed; import.meta.glob calls inside it will fail`)\n    config.ssr = { ...config.ssr, noExternal: [...noExternal, dep] }\n  }\n}","typeGuard":"function isTransformableImport(id: string, config: ResolvedConfig): boolean {\n  // node_modules deps need ssr.noExternal to be transformed\n  if (id.includes('node_modules')) {\n    const noExternal = config.ssr?.noExternal\n    if (Array.isArray(noExternal)) {\n      return noExternal.some(pattern =>\n        pattern instanceof RegExp ? pattern.test(id) : id.includes(pattern)\n      )\n    }\n    return noExternal === true\n  }\n  return true\n}","tryCatchPattern":"// In SSR code that loads external modules\ntry {\n  await import('some-dep')\n} catch (e) {\n  if (e.message.includes('import.meta.glob')) {\n    console.error('Dependency not transformed. Add to ssr.noExternal.')\n  }\n  throw e\n}","preventionTips":["Add dependencies that use import.meta.glob to ssr.noExternal in your Vite config.","Always reference import.meta.glob by its full literal name — never through aliases or computed access.","Ensure your module runner transport fetches modules through the Vite dev server, not raw file reads.","Test SSR imports of third-party dependencies that use Vite-specific features."],"tags":["module-runner","import-meta-glob","ssr","transform","no-external"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}