DEV Community

Mizan-Rifat
Mizan-Rifat

Posted on

Keep Your Monorepo Clean in VS Code with a Workspace Checkout Script

Monorepos can be both a blessing and a curse. They offer a centralized codebase, but managing a large number of applications simultaneously in a Code Editor can quickly become overwhelming. The default behavior of any Code Editor, where all files and folders are visible in the explorer, makes searching for files a cluttered experience and makes the workspace messy.

In VS Code To address this issue and maintain a clean workspace, you can leverage the .vscode/settings.json file. By configuring the files.exclude property, you can hide specific files or folders from the file explorer. For example:

// .vscode/settings.json
{
  "files.exclude": {
    "apps/server": true
  }
}
Enter fullscreen mode Exit fullscreen mode

This will hide the server app from the VS Code explorer without deleting it from the filesystem. However, manually updating this setting can be tedious. To streamline the process, Lets create a Node.js script that dynamically updates the files.exclude settings based on your current needs.

Introducing the Workspace Checkout Script

With this script and the enquirer npm package, you can create a simple command-line interface (CLI) to toggle the visibility of applications in your monorepo. Here’s how you can set it up:

1. install enquirer:

 npm i enquirer
Enter fullscreen mode Exit fullscreen mode

2. Create the script:

Save the following script as scripts/workspace-checkout.js in your project.


import { fileURLToPath } from 'url';
import path, { dirname } from 'path';
import fs, { readdirSync } from 'fs';
import enquirer from 'enquirer';

// Get the current file's directory
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Destructure AutoComplete from enquirer
const { AutoComplete } = enquirer;

// Define paths for the VS Code settings file and the apps directory
const relativeFilePath = '../.vscode/settings.json';
const absoluteFilePath = path.join(__dirname, relativeFilePath);
const appsPath = path.join(__dirname, '../apps');

// List of apps to always exclude
const excludedApps = [];

// Read the VS Code settings file
fs.readFile(absoluteFilePath, 'utf8', async (err, data) => {
  if (err) {
    console.error('Error reading file:', err);
    return;
  }

  let jsonData;
  try {
    // Parse the JSON data from the settings file
    jsonData = JSON.parse(data);
  } catch (parseError) {
    console.error('Error parsing JSON:', parseError);
    return;
  }

  // Determine initially selected apps based on settings
  const initial = Object.keys(jsonData['files.exclude'])
    .filter(app => !jsonData['files.exclude'][app])
    .map(app => app.split('/')[1]);

  // Read the apps directory and filter out excluded apps
  const apps = readdirSync(appsPath, { withFileTypes: true })
    .filter(direct => {
      return direct.isDirectory() && !excludedApps.includes(direct.name);
    })
    .map(direct => direct.name);

  // Create a prompt for selecting apps to display
  const prompt = new AutoComplete({
    name: 'apps',
    message:
      'Press arrow keys to navigate and space to select/deselect apps. Press enter to confirm.',
    multiple: true,
    choices: [...apps],
    initial: initial.filter(app => !excludedApps.includes(app))
  });

  // Get the user's selection
  const answer = await prompt.run();

  // Update the VS Code settings based on the user's selection
  apps.forEach(app => {
    jsonData['files.exclude'][`apps/${app}`] = !answer.includes(app);
  });

  const updatedJsonData = JSON.stringify(jsonData, null, 2);

  // Write the updated settings back to the file
  fs.writeFile(absoluteFilePath, updatedJsonData, 'utf8', writeErr => {
    if (writeErr) {
      console.error('Error writing to file:', writeErr);
      return;
    }
    console.log('Checkout successful.');
  });
});


Enter fullscreen mode Exit fullscreen mode

3.Update your package.json:

Add a script entry to your package.json to run the checkout script.

"scripts": {
  // Others script
  "checkout": "node scripts/workspace-checkout.js"
}

Enter fullscreen mode Exit fullscreen mode

4.Run the script:

Open your terminal and type the following command to run the script:

npm run checkout
Enter fullscreen mode Exit fullscreen mode

This command will present a list of all available apps with a checkmark. Use the spacebar to toggle the selection and press enter to confirm. Only the selected apps will be visible in the VS Code file manager. This keeps your workspace clean and focused on the apps you are currently working on, while still keeping all files intact on the filesystem.

Conclusion

Using a monorepo can significantly enhance collaboration and code management across multiple applications. However, it's essential to keep your development environment organized. By leveraging the .vscode/settings.json file and automating the process with a Node.js script, you can efficiently manage which apps are visible in your VS Code explorer. This approach keeps your workspace clean, enhances productivity, and reduces clutter.

Try setting up this script in your monorepo and enjoy a more streamlined development experience!

And if you have a better approach, please share your insights in the comments. I'm always looking for new and improved ways to manage my development environments effectively.

Top comments (0)