You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VSCode扩展开发:如何用相对路径读取同目录文本文件?

问题

我正在开发一款VSCode扩展,调用encloseTag命令时,会从文本文件加载预设标签列表,将选中文本包裹在选中标签中。目前仅指定静态路径时可正常运行,使用相对路径则报错:

Error reading tags file: ENOENT: no such file or directory, open 'tags.txt'
Activating extension 'undefined_publisher.enclosingtags' failed: ENOENT: no such file or directory, open 'c:\Users\username\ProjectPublisher\out\FILENAME'.

打印工作目录后发现,其并非项目目录(位于AppData而非用户文件夹中的项目位置)。我是通过VSCode按F5调试运行扩展的,请问如何让代码读取与extension.ts同目录的tags.txt文件?

相关代码

package.json

(…)
"contributes": {
    "commands": [
      {
        "command": "encloseTag",
        "title": "Enclose in Tag"
      }
    ]
},
(…)

extension.ts

import * as vscode from 'vscode';
import * as fs from 'fs';

export function activate(context: vscode.ExtensionContext) {
    let disposable = vscode.commands.registerCommand('encloseTag', () => {

        let editor = vscode.window.activeTextEditor;
        if (!editor) {
            vscode.window.showErrorMessage('No active text editor');
            return;
        }
        let selection = editor.selection;
        let text = editor.document.getText(selection);
        if (!text) {
            return;
        }

        let tags: string[] = [];
        try {
            let data = fs.readFileSync('C:\\Users\\username\\ProjectPublisher\\tags.txt', 'utf8');
            // Split the data into lines and remove leading and trailing whitespace and newline characters from each line
            tags = data.split('\n').map(line => line.trim().replace(/\r?\n|\r/g, ''));
        } catch (error: any) {
            vscode.window.showErrorMessage('Error reading tags file: ' + error.message);
            return;
        }

        // Prompt the user to select a tag
        vscode.window.showQuickPick(tags).then((tag) => {
            if (!tag) {
                return;
            }

            // Enclose the selected text in the chosen tag
            let newText = `<${tag}>${text}</${tag}>`;
            editor.edit(edit => {
                edit.replace(selection, newText);
            });
        });
    });

    context.subscriptions.push(disposable);

    const fs = require('fs');
    fs.readFileSync(`${__dirname}\\FILENAME`);
}

export function deactivate() {}

tags.txt

tag1
tag2
tag3
解决方法

核心问题是VSCode扩展调试时的工作目录并非项目源码目录,而是编译后的out目录或临时运行目录,直接用相对路径会找不到文件。要读取和extension.ts同目录的文件,需通过VSCode扩展上下文获取正确路径,步骤如下:

  1. 利用context.extensionPath获取扩展根目录
    context.extensionPath是VSCode提供的上下文属性,会返回扩展项目的根目录路径,调试和发布状态下都能正确获取。

  2. 用path模块拼接文件路径
    借助Node.js的path模块拼接路径,自动处理跨平台路径分隔符差异,避免手动拼接出错。

修改后的extension.ts关键代码:

import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path'; // 新增导入path模块

export function activate(context: vscode.ExtensionContext) {
    let disposable = vscode.commands.registerCommand('encloseTag', () => {

        // 保留原有编辑器检查、选中文本获取的代码

        let tags: string[] = [];
        try {
            // 拼接tags.txt的完整路径
            const tagsFilePath = path.join(context.extensionPath, 'tags.txt');
            let data = fs.readFileSync(tagsFilePath, 'utf8');
            tags = data.split('\n').map(line => line.trim().replace(/\r?\n|\r/g, ''));
        } catch (error: any) {
            vscode.window.showErrorMessage('Error reading tags file: ' + error.message);
            return;
        }

        // 保留后续选择标签、替换文本的代码
    });

    context.subscriptions.push(disposable);

    // 读取其他同目录文件的示例
    const testFilePath = path.join(context.extensionPath, 'FILENAME');
    fs.readFileSync(testFilePath);
}
  1. 确保tags.txt被打包进扩展
    在package.json中添加files字段,确保非代码文件被包含在扩展包中:
{
  "files": [
    "out/**/*.js",
    "tags.txt" // 新增该行
  ]
}

说明

  • context.extensionPath:始终指向扩展的根目录,调试时是项目源码目录,发布后是扩展安装目录。
  • path.join():自动适配Windows和Linux的路径分隔符,避免手动书写分隔符导致的兼容性问题。
  • files字段:确保tags.txt这类资源文件被包含在扩展包内,否则调试或安装后会出现文件缺失错误。

内容的提问来源于stack exchange,提问作者MrVocabulary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:32:09