0

I am creating a NodeJS and Express app and want a module for configuration that runs once on start up then makes a serverConfig object available to any other module that needs these values. So far I have something like this:

const loadConfig = () => {
    // logic to load configuration from environment variables, AWS Secrets Manager, etc.
}

export default loadConfig()

Now I can do

import serverConfig from 'config'

When I do this in multiple files will loadConfig() be called each time? Or will I have access to a reference to a single object from all of my imports? I only want this loadConfig() function to execute once on start up. These config values should not change during execution. And I don't want to repeat the (perhaps) time consuming logic in loadConfig() multiple times during each request to my API.

If not, what is the correct way to call loadConfig() once on server start up and create an object that all other modules can import and reference.

5
  • This will only run once Commented Nov 21, 2022 at 22:11
  • @Konrad Do you have any documentation or references where I can learn more about how import/export works in JavaScript? Especially when it comes to what is executed and when? Commented Nov 21, 2022 at 22:13
  • @Code-Apprentice This has nothing to do with import or export. If you call a function from with in your module, you just can just "export" the return result of that function. Regardless if you module uses "import"/"export" or "module.exports" or "what ever". If you want to make it "dynamic", export the function without calling it. Commented Nov 21, 2022 at 22:24
  • @Marc What if I have import serverConfig from 'config' in two different files? Will the function be called each time the import happens? Commented Nov 21, 2022 at 22:29
  • @Marc And do you have a link to documentation that I can read to learn more? Commented Nov 21, 2022 at 22:31

1 Answer 1

2

Everything in file scope executes once. Once the exports of a file are resolved, they are directly used by reference for any subsequent imports.

Any function call that is is not inside function itself will be executed exactly once when that file is imported when your program first starts up.

// a.ts
console.log('foo')

// b.ts
import './a'

// c.ts
import './a'

// main.ts
import './b'
import './c'

If you compile and run main.ts you will get exactly one output of "foo" to the console.


Given that, your example could be rewritten as:

const loadConfig = () => {
    // logic to load configuration from environment variables, AWS Secrets Manager, etc.
}

const config = loadConfig()

export default config

Now its pretty clear that loadConfig() is called from the file scope and so only executes once.

This version:

export default loadConfig()

just avoids the intermediary variable but otherwise functions exactly the same.


If you did want to run that logic multiple times, you just need to export a function to do it for you.

// config.ts
export const loadConfig = () => {
    // ...
}

// main.ts
import { loadConfig } from './config'

loadConfig()
loadConfig() // now do it again.

That doesn't sound like what you want, but I list it here to make it clear what the difference is.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.