hapipal / discuss

The hapi pal discussion board
3 stars 0 forks source link

exports.deployment Fn in server.js #7

Closed Ba7er closed 2 years ago

Ba7er commented 2 years ago

As a new comer to NodeJS and i was playing around with Hapipal i found a block of code that i could not understand why and could not find the answer online (properly i was looking in the wrong direction) ?

why exporting "deployment and init" functions in server.js like below:

appreciate your explanation

exports.init = async () => {
    const manifest = Manifest.get('/');
    const server = await Glue.compose(manifest, { relativeTo: __dirname });

    await server.initialize();
    return server;
};

exports.deployment = async (start) => {
    const server = await exports.init();
    if (!start) {
        return server;
    }

    registerLifecycleEvents(server);
    await server.start();

    server.log(`Server started at ${server.info.uri}`);

    if (process.env.NODE_ENV !== 'production') {
        server.events.on('log', (event, tags) => {
            if (tags.error) {
                console.log(event.error.stack);
            }
        });
    }

    return server;
};
devinivy commented 2 years ago

This code doesn't look like anything directly from hapi pal, but it seems like it could be based the server entrypoint in the pal boilerplate: https://github.com/hapipal/boilerplate/blob/839e7af40bb32558bf9cebaaeef3ec4cf3d9d5be/server/index.js#L7-L31

The purpose of that code is to provide a function to create a new hapi server. This can be used as needed in tests, like so: https://github.com/hapipal/boilerplate/blob/839e7af40bb32558bf9cebaaeef3ec4cf3d9d5be/test/index.js#L17-L21

For tests I would recommend initializing your server (server.initialize()), but not starting your server (server.start()). The former runs hapi's onPreStart extensions, starts caches, and ensures all plugin dependencies are satisfied. The latter is exactly the same, but it also causes the server to start listening for requests from the network. Generally the network is not needed for tests since hapi's server.inject() allows you to simulate requests to your server.

In the code snippet you posted, you can see that exports.init() creates a server then initializes it, while exports.deployment(true) creates a server then starts it. So I would expect in that example exports.init() to be used for tests, and exports.deployment(true) to be used when you want to run your server in production.

Ba7er commented 2 years ago

@devinivy , Thanks for the reply. The snippet that i have shared is available in server.js that has been created after i initiated the project using npm init @hapipal projectName

I totally understand what these two function do, the only confusion i had is why to export them. Anyways your explanation cleared out the confusion and those two functions are exported so we can use them in test files.

Thanks.

devinivy commented 2 years ago

That is interesting— after I run npm init @hapipal projectName I don't have a server.js file, but I do have a server/index.js file with these contents:

'use strict';

const Glue = require('@hapi/glue');
const Exiting = require('exiting');
const Manifest = require('./manifest');

exports.deployment = async ({ start } = {}) => {

    const manifest = Manifest.get('/', process.env);
    const server = await Glue.compose(manifest, { relativeTo: __dirname });

    if (start) {
        await Exiting.createManager(server).start();
        server.log(['start'], `Server started at ${server.info.uri}`);
        return server;
    }

    await server.initialize();

    return server;
};

if (require.main === module) {

    exports.deployment({ start: true });

    process.on('unhandledRejection', (err) => {

        throw err;
    });
}

Are you sure that the snippet you posted came directly from npm init @hapipal?

Ba7er commented 2 years ago

Apologies @devinivy , the file name is "index.js" and not "server.js". i have confused between two files i have opened locally. However my question remains the same regarding exporting "deployment" function.

Thanks again

devinivy commented 2 years ago

You're welcome! The key in there is that if (require.main === module) { will ensure the server starts running when the file is invoked as a script, e.g. node server/index.js. But when you require('../server/index.js') in a test, the server will not automatically start running.