babalae/better-genshin-impact · error · FileNotFoundException

不支持的模块导入类型: '{specifier}' (仅支持 .js 文件)

Error message

不支持的模块导入类型: '{specifier}' (仅支持 .js 文件)

What it means

Thrown by PackageDocumentLoader.LoadDocumentAsync when a module import path is resolved successfully but the file extension is not .js. The document loader only supports JavaScript module imports — JSON, CSS, images, and other file types cannot be imported as ES modules through this path (though images are handled specially via RewriteScriptCode for resource interception).

Source

Thrown at BetterGenshinImpact/Core/Script/PackageDocumentLoader.cs:60

                throw new FileNotFoundException($"无法解析模块导入路径: '{specifier}'", specifier);
            }

            // 处理 JS 文件的重写
            if (Path.GetExtension(targetPath).ToLower() == ".js")
            {
                var uri = new Uri(targetPath);

                // 检查缓存
                var cached = GetCachedDocument(uri);
                if (cached != null) return cached;

                string content = await File.ReadAllTextAsync(targetPath);
                string processedCode = RewriteScriptCode(content, targetPath);
                var documentInfo = new DocumentInfo(uri) { Category = ModuleCategory.Standard };
                return CacheDocument(new StringDocument(documentInfo, processedCode), false);
            }

            throw new FileNotFoundException($"不支持的模块导入类型: '{specifier}' (仅支持 .js 文件)", specifier);
        }

        /// <summary>
        /// js重写
        /// </summary>
        public string RewriteScriptCode(string code, string currentFilePath)
        {
            if (string.IsNullOrEmpty(code)) return code;

            string result = code.Replace("../../../packages", "packages");

            // 拦截资源导入
            var resourceRegex = new Regex(@"import\s+([\w\d_*$]+|[\s\S]*?)\s+from\s+(['""])([^'""\n]+)(['""])");
            result = resourceRegex.Replace(result, match =>
            {
                string importPart = match.Groups[1].Value.Trim();
                string quote = match.Groups[2].Value;
                string path = match.Groups[3].Value.Replace("../../../packages", "packages");

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Only import .js files as ES modules in this script system.
  2. For JSON data, read it at runtime using the file API (e.g. file.readText()) and JSON.parse() instead of import.
  3. Rename the target file to .js and export its contents as a JS module.
  4. For image resources, use the supported resource import pattern handled by RewriteScriptCode.

Example fix

// before
import config from './config.json';
// after
const config = JSON.parse(file.readText('./config.json'));
Defensive patterns

Strategy: validation

Validate before calling

if (!specifier.EndsWith(".js", StringComparison.OrdinalIgnoreCase))
{
    throw new NotSupportedException($"Only .js imports are supported, got: {specifier}");
}

Type guard

static bool IsJsModule(string specifier) =>
    specifier.EndsWith(".js", StringComparison.OrdinalIgnoreCase);

Prevention

When it happens

Trigger: A JS script attempts to import a non-.js file as an ES module, e.g. import config from './config.json' or import styles from './styles.css'. The loader resolves the file path but rejects it because only .js files are valid module entry points in this system.

Common situations: Script author tries to use Node.js-style JSON imports (require('./config.json')) which aren't supported in this ClearScript-based environment. Importing TypeScript files directly. Attempting to import a .mjs or .cjs file.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/039820caeedc2f1f. Report an issue: GitHub.