npm | Check if there is a local-npm server running on Brian's machine | Cell 3 | Search

This code provides a customized npm execution function that allows for controlled npm command execution within a specific project directory. It handles installation, error management, and progress logging, making it a more robust way to interact with npm within a larger application.

Run example

npm run import -- "Run NPM in javscript with in-memory file-system"

Run NPM in javscript with in-memory file-system

var execSync = require('child_process').execSync;
try {
    require.resolve('npm');
} catch (e) {
    execSync('npm install npm');
}

function npm(project, args, conf) {
    var previous = process.cwd();
    process.chdir(project);
    return importer
        .import("memory-fs rewire")
        .then(r => {
            // set up project path
            return new Promise((resolve, reject) => {
                //if(typeof mockTypescriptFs == 'undefined') {
                //    mockTypescriptFs = eval("'use strict';" + r[0].code);
                // overlay out temp filesystem on top of current filesystem
                //    mockTypescriptFs(project, data);
                //}

                var cli = require('npm');
                cli.load(conf, (err) => {
                    // handle errors
                    if (err) {
                        return reject(err);
                    }

                    // install module
                    cli.commands[args[0]](args.slice(1), (er, data) => {
                        if (er) {
                            return reject(er);
                        }
                        // log errors or data
                        resolve(data);
                    });

                    cli.on('log', (message) => {
                        // log installation progress
                        console.log(message);
                    });
                });
            });
        })
        .then((r => {
            process.chdir(previous);

            return r;
        }));
};
module.exports = npm;

What the code could have been:

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const npm = require('npm');
const { importPlugin } = require('@pluginjs/import');

const installNpm = async () => {
    try {
        await require.resolve('npm');
    } catch (e) {
        // Install npm package when it's not installed
        execSync('npm install npm');
    }
};

const runNpm = async (project, args, config) => {
    // Get the current directory
    const currentDir = process.cwd();
    try {
        // Change to the project directory
        await fs.promises.chroot(project);

        // Import required modules
        const {
            default: importFs,
            rewire,
        } = await importPlugin(['memory-fs','rewire']);

        // Set up project path
        const projectPath = path.join(project, 'package.json');

        // Check if package.json file exists
        const packageJson = await fs.promises.readFile(projectPath, 'utf8');
        if (!packageJson) {
            throw new Error('Package.json file not found');
        }

        // Load npm configuration
        npm.load(config, (err) => {
            if (err) {
                throw err;
            }

            // Run npm command
            npm.commands[args[0]](...args.slice(1), (err, data) => {
                if (err) {
                    throw err;
                }
                // Log data or errors
                globalThis.console.log(data);
            });
        });
    } catch (error) {
        throw error;
    } finally {
        // Change back to the original directory
        await fs.promises.chroot(currentDir);
    }
};

// Export the function
module.exports = runNpm;

This code defines a function npm that provides a wrapper around the npm package manager, allowing for more controlled execution within a specific project directory.

Here's a breakdown:

  1. npm Installation Check:

  2. npm Function:

  3. Module Export:

Let me know if you have any more questions!