npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

entry-script

v3.0.6

Published

Modular control for entry script execution.

Downloads

787

Readme

entry-script

Modular control for entry script execution.

npm package License

Contents

Introduction

Modular control for entry script execution.

Many top-level NodeJS executables look something like:

// bin.ts
import express from 'express.js';
import { database } from './my-database.js';
import { middleware } from './my-middleware.js';

await database.connect();

const app = express();
app.use(middleware);

app.listen(3000);

This file is not testable, extendable, or modular because it executes the moment it is loaded. It is not possible to stub methods like database.connect in a test suite.

entry-script solves this by providing a light class to extend and export as default. The internals of EntryScript detect that the class is the top-level script, and kicks off the process.

But during a test environment where it is not the top-level script, nothing is executed! That allows you to mock and inspect methods as necessary to fully test your code.

Install

npm i entry-script

Example

// my-app.ts
import { EntryScript } from 'entry-script';
import express, { type Application } from 'express';
import { database } from './my-database.js';
import { middleware } from './my-middleware.js';

/**
 * Class will be picked up by unit/integration tests to
 * provide mock dependencies
 */
export class MyApp extends EntryScript {

    #app: Application;
    #database: typeof database;

    constructor(application = express(), db = database) {
        this.#app = application;
        this.#database = db;
    }

    // node ./my-app.js --port 8080
    public override async main([, port = '8080']: string[]): Promise<void> {
        await database.connect();

        app.use(middleware);

        app.listen(parseInt(port));

        await new Promise((resolve, reject) => {
            // Graceful shutdown
            process.once('SIGTERM', () => {
                resolve();
            });
        });

        await database.disconnect();
    }
}

// Instance will be picked up when this file is executed directly!
export default new MyApp();

Now executing node ./my-app.js will start the server as expected!

But import MyApp from './my-app.js'; will return the app class that is ripe for unit/integration testing!

Usage

entry-script is an ESM module. That means it must be imported. To load from a CJS module, use dynamic import const { EntryScript } = await import('entry-script');.

Any class that extends EntryScript must export either the class itself or an instance of the class as the default export.

Depending on class/instance export, either the static or instance version of main(argv: string[]): Promise<void> must be implemented.

API

EntryScript

Extendable class that control logic flow of an entry point. Will not perform any execution if the entry point for nodejs does not export a child class of EntryScript as default.

This class is exported both as the default export of this package, and as a named export.

main(argv: string[]): Promise

Available as both a static and instance method.

If a class is exported, will call the static method, if an instance is exported will call the instance method. Only one will be called, and it must be implemented.

In general this method should not be called directly during production, as it is called implicitly by the internal EntryScript lifecycle, although it may be called as part of your unit/integration tests (thats the whole idea!).

The array of parameters passed to it are the command line arguments. T hey are the same as process.argv, minus the node executable and filename:

node ./foo-bar.js --port 8080 -> argv = ['--port', '8080'].

Also See

haywire-launcher

Manage dependency injection alongside entrypoint handling!

import { launch } from 'haywire-launcher';
import { myContainer } from './container.js';

export default launch(myContainer);