Numeric Production Mechanism

    @rushstack/rundown

    1.0.172 • Public • Published

    @rushstack/rundown

    Slow startup times for Node.js commands or services? Rundown can invoke a Node.js process and:

    1. View imported files: Intercept all require() calls and show which paths were loaded.
    2. Find culprits: Show the chain for require() calls for each import, explaining why it was imported.
    3. Detect regressions over time: Generate a concise "snapshot" report that can be committed to Git. Changes to this file may indicate potential performance regressions.

    Installation

    You can install this tool globally:

    $ npm install --global @rushstack/rundown
    
    # View command line help
    $ rundown --help

    If you will generate rundown snapshots during your build, it is recommended to install via devDependencies:

    $ cd my-tool
    $ npm install @rushstack/rundown --save-dev

    Viewing imported files

    Suppose you maintain a small NPM project that is invoked as follows:

    # The folder where your tool is developed
    $ cd my-tool
    
    # When you invoke "my-tool --my-option 123 --verbose" from the shell, let's suppose that it invokes
    # this Node.js command:
    $ node lib/start.js --my-option 123 --verbose

    And suppose that your tool's startup time is rather slow, because the code calls require() to load many different NPM packages. We can create a report to see all the imports:

    # We use "--args" to pass the command-line arguments for "my-tool"
    $ rundown inspect --script lib/start.js --args="--my-option 123 --verbose"

    The report may look like this:

    rundown-inspect.log

    /path/to/my-tool/lib/start.js
    /path/to/my-tool/node_modules/at-least-node/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/copy-sync/copy-sync.js
    /path/to/my-tool/node_modules/fs-extra/lib/copy-sync/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/copy/copy.js
    /path/to/my-tool/node_modules/fs-extra/lib/copy/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/empty/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/file.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/link.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-paths.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-type.js
    /path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink.js
    /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/json/jsonfile.js
    /path/to/my-tool/node_modules/fs-extra/lib/json/output-json-sync.js
    /path/to/my-tool/node_modules/fs-extra/lib/json/output-json.js
    /path/to/my-tool/node_modules/fs-extra/lib/mkdirs/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/mkdirs/make-dir.js
    /path/to/my-tool/node_modules/fs-extra/lib/move-sync/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/move-sync/move-sync.js
    /path/to/my-tool/node_modules/fs-extra/lib/move/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/move/move.js
    /path/to/my-tool/node_modules/fs-extra/lib/output/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/path-exists/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/remove/index.js
    /path/to/my-tool/node_modules/fs-extra/lib/remove/rimraf.js
    /path/to/my-tool/node_modules/fs-extra/lib/util/stat.js
    /path/to/my-tool/node_modules/fs-extra/lib/util/utimes.js
    /path/to/my-tool/node_modules/graceful-fs/clone.js
    /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
    /path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
    /path/to/my-tool/node_modules/graceful-fs/polyfills.js
    /path/to/my-tool/node_modules/jsonfile/index.js
    /path/to/my-tool/node_modules/jsonfile/utils.js
    /path/to/my-tool/node_modules/universalify/index.js
    

    Finding callers

    To see how each file is imported, you can add the --trace-imports switch.

    # We use "--args" to pass the command-line arguments for "my-tool"
    $ rundown inspect --script lib/start.js --args="--my-option 123 --verbose" --trace-imports

    The report now shows more detail:

    rundown-inspect.log

    . . .
    /path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
      imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
      imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
      imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
      imported by /path/to/my-tool/lib/start.js
      imported by /rundown/lib/launcher.js
    
    /path/to/my-tool/node_modules/graceful-fs/polyfills.js
      imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
      imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
      imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
      imported by /path/to/my-tool/lib/start.js
      imported by rundown/lib/launcher.js
    . . .
    

    Fixing problems

    It may be the case that many of these imports are not actually used. You can avoid preloading them by converting them to lazy imports using the Import.lazy() from @rushstack/node-core-library or import-lazy.

    Generating a snapshot

    To detect future regressions, use the rundown snapshot command to write a snapshot file:

    # We use "--args" to pass the command-line arguments for "my-tool"
    $ rundown snapshot --script lib/start.js --args="--my-option 123 --verbose"
    
    # This file can be committed to Git to track regressions
    $ git add rundown-snapshot.log

    The snapshot file format eliminates spurious diffs, by showing only the names of the imported packages. For local projects in a monorepo, it will show relative paths. Example output:

    rundown-snapshot.log

    ../path/to/monorepo-sibling
    at-least-node
    fs-extra
    graceful-fs
    jsonfile
    universalify
    

    Command-line reference

    usage: rundown [-h] <command> ...
    
    Detect load time regressions by running an app, tracing require() calls, and
    generating a deterministic report
    
    Positional arguments:
      <command>
        snapshot  Invoke a Node.js script and generate a test snapshot
        inspect   Invoke a Node.js script and generate detailed diagnostic output
    
    Optional arguments:
      -h, --help  Show this help message and exit.
    
    For detailed help about a specific command, use: rundown <command> -h
    
    usage: rundown snapshot [-h] -s PATH [-a STRING] [-q] [-i]
    
    Invoke a Node.js script and generate a test snapshot. This command creates a
    concise report that can be added to Git, so that its diff can be used to
    detect performance regressions
    
    Optional arguments:
      -h, --help            Show this help message and exit.
      -s PATH, --script PATH
                            The path to a .js file that will be the entry point
                            for the target Node.js process
      -a STRING, --args STRING
                            Specifies command-line arguments to be passed to the
                            target Node.js process. The value should be a single
                            text string delimited by spaces. Example: rundown
                            inspect --scripts ./example.js --args="--flag
                            --option=123"
      -q, --quiet           Suppress STDOUT/STDERR for the target Node.js process
      -i, --ignore-exit-code
                            Do not report an error if the target Node.js process
                            returns a nonzero exit code
    
    usage: rundown inspect [-h] -s PATH [-a STRING] [-q] [-i] [-t]
    
    Invoke a Node.js script and generate detailed diagnostic output. This command
    is used to inspect performance regressions.
    
    Optional arguments:
      -h, --help            Show this help message and exit.
      -s PATH, --script PATH
                            The path to a .js file that will be the entry point
                            for the target Node.js process
      -a STRING, --args STRING
                            Specifies command-line arguments to be passed to the
                            target Node.js process. The value should be a single
                            text string delimited by spaces. Example: rundown
                            inspect --scripts ./example.js --args="--flag
                            --option=123"
      -q, --quiet           Suppress STDOUT/STDERR for the target Node.js process
      -i, --ignore-exit-code
                            Do not report an error if the target Node.js process
                            returns a nonzero exit code
      -t, --trace-imports   Reports the call chain for each module path, showing
                            how it was imported
    

    Links

    Rundown is part of the Rush Stack family of projects.

    Keywords

    none

    Install

    npm i @rushstack/rundown

    Homepage

    rushstack.io

    DownloadsWeekly Downloads

    100

    Version

    1.0.172

    License

    MIT

    Unpacked Size

    154 kB

    Total Files

    38

    Last publish

    Collaborators

    • odspnpm
    • rushstack