VSCode Webview API批量导入JSON文件夹及fs模块报错求助
Hey there! Let's tackle this problem step by step. The key issue here is that VSCode Webviews run in a browser-like context, not a Node.js environment—so you can't use the fs module directly, which is why you're seeing that fs.readdirSync is not a function error.
Below are two reliable solutions depending on your use case:
1. Static Batch Import (For Fixed Files)
If your test folder's JSON files don't change dynamically (you know all filenames upfront), you can use Webpack's built-in require.context to import them all at compile time. This works seamlessly with VSCode extension's default Webpack setup.
// Create a helper function to batch import and map files to input variables const importTestFiles = (requireContext: __WebpackModuleApi.RequireContext) => { const inputs: { [key: string]: any } = {}; requireContext.keys().forEach(filePath => { // Extract the number from filename (e.g., test1.json → 1) const fileNumberMatch = filePath.match(/\/test(\d+)\.json/); if (fileNumberMatch) { const varName = `input${fileNumberMatch[1]}`; inputs[varName] = requireContext(filePath); } }); return inputs; }; // Import all JSON files in the test folder const inputs = importTestFiles(require.context('../test', false, /\.json$/)); // Access your data like this: console.log(inputs.input1); // Equivalent to your original import input1 console.log(inputs.input5);
Note: Make sure your tsconfig.json has "allowSyntheticDefaultImports": true to avoid type errors with Webpack's require.context.
2. Dynamic File Loading (For Variable/Dynamic Files)
If your test folder might have new files added at runtime, you'll need to leverage VSCode's extension main process (which runs in Node.js and can access fs) to read files, then send the data to your Webview via message passing.
Step 1: Add Message Handling in Extension Main Process (extension.ts)
import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; export function activate(context: vscode.ExtensionContext) { // Register command to open your Webview context.subscriptions.push( vscode.commands.registerCommand('yourExtension.loadTestData', () => { const panel = vscode.window.createWebviewPanel( 'testDataPanel', 'Test Data', vscode.ViewColumn.One, { enableScripts: true } ); // Listen for requests from the Webview panel.webview.onDidReceiveMessage( async (message) => { if (message.command === 'fetchTestFiles') { // Path to your test folder const testDir = path.join(context.extensionPath, 'test'); const testFiles: { [key: string]: any } = {}; // Read and parse all JSON files fs.readdirSync(testDir) .filter(file => file.endsWith('.json')) .forEach(filename => { const fileContent = fs.readFileSync(path.join(testDir, filename), 'utf-8'); const varName = `input${filename.match(/test(\d+)\.json/)?.[1]}`; testFiles[varName] = JSON.parse(fileContent); }); // Send data back to Webview panel.webview.postMessage({ command: 'testFilesLoaded', data: testFiles }); } }, undefined, context.subscriptions ); // Webview HTML with script to handle messages panel.webview.html = getWebviewContent(); }) ); } function getWebviewContent() { return ` <!DOCTYPE html> <html> <body> <script> // Request data from extension main process window.postMessage({ command: 'fetchTestFiles' }, '*'); // Receive and use the data window.addEventListener('message', (event) => { if (event.data.command === 'testFilesLoaded') { const inputs = event.data.data; console.log(inputs.input1); // Access your imported JSON data here } }); </script> </body> </html> `; }
Step 2: Use the Data in Your Webview
Once the Webview receives the testFilesLoaded message, you'll have access to all your input1 to inputN variables via the inputs object, just like your original individual imports.
内容的提问来源于stack exchange,提问作者Nihar

