Napoleon's Penguin Mascot

    expose-require

    1.3.5 • Public • Published

    Expose and Require

    NodeJS build

    Adds "module.exports" to a file, exposing:

    • globally defined variables (either with const, let or var);
    • globally declared functions with "function" keyword;
    • classes declared with class keyword (including child classes with extends);

    Updated file is then saved to the target path and required. If target or source path does not exist or the file can't be read or written, the module will attempt to resolve the issues.

    WARNING The module is asynchronous, use async / await or promises to avoid race conditions.

    Basic usage

    exposeAndRequire function accepts three parameters:

    1. Path to the source file (required)
    2. Path to the target folder
    3. Options object, specifying actions / additional parameters:
    • color colorize log output (using color escape sequences)
    • exposeOnly forces module to return null and do not require exposed file
    • grep each line will be matched against and performed replacements on accordingly
    • log redirects logging output of the module (see logging ):
      • to a file if path is given
      • to a stream if given a Stream
    • require output file will be prepended with require statements
    • use root to resolve against for required modules, can be either:
      • root paths are relative to "." default
      • cwd paths are relative to process.cwd() dynamic
      • module paths are relative to module folder
    const ER = require('expose-require');
     
    ER
        .exposeAndRequire('lib/index.js','test',{
            require: {
                'fs': 'fs',
                '{ someFunc }': 'someModule'
            },
            grep: [{
                match: /(\d+)/,
                replace: '$1$1'
            }],
            use: "module"
        })
        .then(module => {
            //do stuff;
        });
     

    Usage with source path only

    You can omit both the target path and opions, in which case the file will be created in the root directory (passing an empty string as the second agrument results is treated the same way):

    const { exposeAndRequire } = require('expose-require');
     
    //inside async function
    const someModule = await exposeAndRequire('test/test.js');
     
    //with empty string
    const yummy = await exposeAndRequire('dinner/steak.js','');
     
    //do stuff;
     

    Exposing classes

    Given a class or a child class declaration, the module will add it to the current module.exports.

    class BaseClassLine {}
    class BaseClass {
        constructor() {
     
        }
    }
        //tabulated declaration
        class BaseClassTabbed {
            constructor() {
                
            }
        }
     
        //spaced declaration
        class BaseClassSpaced {
            constructor() {
     
            }
        }
     
    class ChildClassLine extends BaseClass {}
    class ChildClass extends BaseClass {
        constructor() {
            
        }
    }

    exposes:

    module.exports = exports = {
        BaseClassLine,
        BaseClass,
        BaseClassTabbed,
        BaseClassSpaced,
        ChildClassLine,
        ChildClass
    };

    Exposing global variables

    Given a variable declared in a global scope, the module will add it to module.exports regardless of keyword used: const, let, or var.

    const constVar = () => console.warn('Be warned!');
     
    let letVar = function () {
        const rand = Math.floor(Math.random() * 2);
     
        const mood = new Map()
            .set(0, () => 'Sometimes I feel blue')
            .set(1, () => 'But other times I cheer!');
     
        return mood.get(rand);
    };
     
    var varVar = 42;

    exposes:

    module.exports = exports = {
        constVar,
        letVar,
        varVar
    };

    Nested declarations

    As of 1.3.0 the module ignores nested declarations. For example, given a source file:

    const functionWithNestedFuncions = function () {
     
        function nested() {
            const inner = 'This should be unreachable';
        }
     
    }

    its module.exports will not expose nested function or inner variable:

    module.exports = exports = {
        functionWithNestedFuncions
    };

    Overriding require sources

    To require a module without relation to target path, you can prefix the path with [relation]::, where relation is one of the use option values.

    In the example below, without root::, path to required coolModule would be resolved as [module folder]/mocks/coolModule.js, instead, it is resolved as [project root]/coolModule.js:

    const awesomeModule = await exposeAndRequire('pathToModule','mocks',{
        require: {
            "{ doCool }" : "root::coolModule.js"
        },
        use: "module"
    });

    Caching

    Since Node.js caches modules in require.cache object, right before the exposed module is required, module cache is cleared (only the exposed entry will be deleted) to ensure the module is reloaded.

    Side note: although the module will clear output cache, make sure you clear parent module cache if watching source files for changes.

    Fallbacks

    If any path in exposure lifecycle does not exist, it will be created. If a folder is missing, it will be created recursively. If a file is missing, it will be created, as well as any folder not existing in path (even if this is a source file).

    Logging

    By default, the module outputs status messages on stdout using chalk. If you intend to save or process logs, remember to remove colour escape sequences.

    [RESOLVED] Created source: mocks/no-such-file.js success

    [EXPOSED] test/source/tested.js => test/mocks

    [FAILED] Could not process file

    The module can redirect logging output for you if you need to export to a file or send to logging service (see log and color options).

    Versions

    Current version is 1.3.5

    Version Features Squashed 🐞
    1.0.0 Initial feature set -
    1.1.0 Added "mute", "log" and "color" options Output folder location issues
    1.2.0 Added module cache clearing Folders with spaces escaping
    1.3.0 Nested declarations are ignored -
    1.3.3 - Edge case of "} else if {}" correctly decreases nestedness
    1.3.4Added `exposeOnly` option
    Added path validation
    -

    Install

    npm i expose-require

    DownloadsWeekly Downloads

    0

    Version

    1.3.5

    License

    MIT

    Unpacked Size

    51.5 kB

    Total Files

    15

    Last publish

    Collaborators

    • 0valt