Skip to content
索引

解析配置

原始代码

js
 public async getResolvedConfig(
    { fileName, uri }: TextDocument,
    vscodeConfig: PrettierVSCodeConfig
  ): Promise<"error" | "disabled" | PrettierOptions | null> {
    const isVirtual = uri.scheme !== "file" && uri.scheme !== "vscode-userdata";

    let configPath: string | undefined;
    try {
      if (!isVirtual) {
        configPath = (await prettier.resolveConfigFile(fileName)) ?? undefined;
      }
    } catch (error) {
      this.loggingService.logError(
        `Error resolving prettier configuration for ${fileName}`,
        error
      );

      return "error";
    }

    const resolveConfigOptions: PrettierResolveConfigOptions = {
      config: isVirtual
        ? undefined
        : vscodeConfig.configPath
        ? getWorkspaceRelativePath(fileName, vscodeConfig.configPath)
        : configPath,
      editorconfig: isVirtual ? undefined : vscodeConfig.useEditorConfig,
    };

    let resolvedConfig: PrettierOptions | null;
    try {
      resolvedConfig = isVirtual
        ? null
        : await prettier.resolveConfig(fileName, resolveConfigOptions);
    } catch (error) {
      this.loggingService.logError(
        "Invalid prettier configuration file detected.",
        error
      );
      this.loggingService.logError(INVALID_PRETTIER_CONFIG);

      return "error";
    }
    if (resolveConfigOptions.config) {
      this.loggingService.logInfo(
        `Using config file at '${resolveConfigOptions.config}'`
      );
    }

    if (resolvedConfig) {
      resolvedConfig = this.resolveConfigPlugins(resolvedConfig, fileName);
    }

    if (!isVirtual && !resolvedConfig && vscodeConfig.requireConfig) {
      this.loggingService.logInfo(
        "Require config set to true and no config present. Skipping file."
      );
      return "disabled";
    }
    return resolvedConfig;
  }
 public async getResolvedConfig(
    { fileName, uri }: TextDocument,
    vscodeConfig: PrettierVSCodeConfig
  ): Promise<"error" | "disabled" | PrettierOptions | null> {
    const isVirtual = uri.scheme !== "file" && uri.scheme !== "vscode-userdata";

    let configPath: string | undefined;
    try {
      if (!isVirtual) {
        configPath = (await prettier.resolveConfigFile(fileName)) ?? undefined;
      }
    } catch (error) {
      this.loggingService.logError(
        `Error resolving prettier configuration for ${fileName}`,
        error
      );

      return "error";
    }

    const resolveConfigOptions: PrettierResolveConfigOptions = {
      config: isVirtual
        ? undefined
        : vscodeConfig.configPath
        ? getWorkspaceRelativePath(fileName, vscodeConfig.configPath)
        : configPath,
      editorconfig: isVirtual ? undefined : vscodeConfig.useEditorConfig,
    };

    let resolvedConfig: PrettierOptions | null;
    try {
      resolvedConfig = isVirtual
        ? null
        : await prettier.resolveConfig(fileName, resolveConfigOptions);
    } catch (error) {
      this.loggingService.logError(
        "Invalid prettier configuration file detected.",
        error
      );
      this.loggingService.logError(INVALID_PRETTIER_CONFIG);

      return "error";
    }
    if (resolveConfigOptions.config) {
      this.loggingService.logInfo(
        `Using config file at '${resolveConfigOptions.config}'`
      );
    }

    if (resolvedConfig) {
      resolvedConfig = this.resolveConfigPlugins(resolvedConfig, fileName);
    }

    if (!isVirtual && !resolvedConfig && vscodeConfig.requireConfig) {
      this.loggingService.logInfo(
        "Require config set to true and no config present. Skipping file."
      );
      return "disabled";
    }
    return resolvedConfig;
  }

解析配置文件

先看这里,prettier.resolveConfig这个方法用于解析配置文件

第一个参数为配置文件的路径,第二个参数为解析配置文件的选项设置,返回解析后的prettier规则

js
 let resolvedConfig: PrettierOptions | null
        try {
            resolvedConfig = isVirtual
                ? null
                : await prettier.resolveConfig(fileName, resolveConfigOptions)
        } catch (error) {
            this.loggingService.logError('Invalid prettier configuration file detected.', error)
            this.loggingService.logError(INVALID_PRETTIER_CONFIG)

            return 'error'
        }
 let resolvedConfig: PrettierOptions | null
        try {
            resolvedConfig = isVirtual
                ? null
                : await prettier.resolveConfig(fileName, resolveConfigOptions)
        } catch (error) {
            this.loggingService.logError('Invalid prettier configuration file detected.', error)
            this.loggingService.logError(INVALID_PRETTIER_CONFIG)

            return 'error'
        }

获取配置文件的路径

prettier.resolveConfigFile用于查找给定的路径下的prettier配置文件,找不到返回null,找到返回配置文件的路径

js
 const isVirtual = uri.scheme !== "file" && uri.scheme !== "vscode-userdata";

    let configPath: string | undefined;
    try {
      if (!isVirtual) {
        configPath = (await prettier.resolveConfigFile(fileName)) ?? undefined;
      }
    } catch (error) {
      this.loggingService.logError(
        `Error resolving prettier configuration for ${fileName}`,
        error
      );

      return "error";
    }
 const isVirtual = uri.scheme !== "file" && uri.scheme !== "vscode-userdata";

    let configPath: string | undefined;
    try {
      if (!isVirtual) {
        configPath = (await prettier.resolveConfigFile(fileName)) ?? undefined;
      }
    } catch (error) {
      this.loggingService.logError(
        `Error resolving prettier configuration for ${fileName}`,
        error
      );

      return "error";
    }

解析配置文件的选项设置

configeditorconfig属性分别表示配置文件路径和.editorconfig文件路径,prettier会解析.editorconfig文件生成相应的prettier规则

isVirtual为真,配置项为undefined isVirtual不为真,vscodeConfig.configPath存在,使用vscodeConfig.configPath的配置项 isVirtual不为真,vscodeConfig.configPath不存在,使用configPath即配置文件的配置项(有可能是undefined)

js
   const resolveConfigOptions: PrettierResolveConfigOptions = {
            config: isVirtual
                ? undefined
                : vscodeConfig.configPath
                ? getWorkspaceRelativePath(fileName, vscodeConfig.configPath)
                : configPath,
            editorconfig: isVirtual ? undefined : vscodeConfig.useEditorConfig,
        }
   const resolveConfigOptions: PrettierResolveConfigOptions = {
            config: isVirtual
                ? undefined
                : vscodeConfig.configPath
                ? getWorkspaceRelativePath(fileName, vscodeConfig.configPath)
                : configPath,
            editorconfig: isVirtual ? undefined : vscodeConfig.useEditorConfig,
        }

清除模块和配置的缓存

js
    public async dispose() {
        prettier.clearConfigCache()
        this.path2Module.forEach(module => {
            try {
                module.clearConfigCache()
            } catch (error) {
                this.loggingService.logError('Error clearing module cache.', error)
            }
        })
        this.path2Module.clear()
    }
    public async dispose() {
        prettier.clearConfigCache()
        this.path2Module.forEach(module => {
            try {
                module.clearConfigCache()
            } catch (error) {
                this.loggingService.logError('Error clearing module cache.', error)
            }
        })
        this.path2Module.clear()
    }

判断文件是否应该被解析

ts
  fileInfo = await prettierInstance.getFileInfo(fileName, {
        ignorePath: resolvedIgnorePath,
        resolveConfig: true,
        withNodeModules: vscodeConfig.withNodeModules,
      });
  fileInfo = await prettierInstance.getFileInfo(fileName, {
        ignorePath: resolvedIgnorePath,
        resolveConfig: true,
        withNodeModules: vscodeConfig.withNodeModules,
      });

返回结果:

json
{
  ignored: boolean,
  inferredParser: string | null,
}
{
  ignored: boolean,
  inferredParser: string | null,
}

ignored表示这个文件是否是应该忽视的,受options.ignorePathoptions.withNodeModules影响

ts
  if (!options.force && fileInfo && fileInfo.ignored) {
      this.loggingService.logInfo("File is ignored, skipping.");
      this.statusBar.update(FormatterStatus.Ignore);
      return;
    }
  if (!options.force && fileInfo && fileInfo.ignored) {
      this.loggingService.logInfo("File is ignored, skipping.");
      this.statusBar.update(FormatterStatus.Ignore);
      return;
    }

Released under the MIT License.