简体   繁体   中英

How to export the instance of the class which is imported dynamically with ES6 module in NodeJS?

I'm reading the book introducing NodeJS with a simple web application example. The requirement in the example is that there are several data store classes in its own module, and we need to adopt the data store dynamically by setting environment variable. The code snippets of the example is something like following:

// memory-store.mjs
// The data store for storing data in memory

export default class MemoryStore {
  // Some CRUD operation
}
// fs-store.mjs
// The data store for storing data into file system

export default class FSStore {
    // Some CRUD operation
}
// store.mjs
// Provide a async function to import data store dynamically and
// set the instance to variable store, which is exported

let store;

async function load() {
    try {
        const moduleName = process.env.MODULE_NAME ?? 'memory';
        const storeModule = await import(`./${moduleName}-store.mjs`);
        const storeClass = storeModule.default;
        store = new storeClass();
        return store;
    } catch(err) {
        throw new Error('Something goes wrong...');
    }
}

export { load, store };
// app.mjs
// Import the function to load the data store dynamically and
// the exported store for fetching data list

import express from 'express';
import { load, store } from './store.mjs';

const app = express();

load()
.then(store => {})
.catch(err => console.error(`Exception with error: ${err}`));

app.use('/', (req, res, next) => {
    const dataList = store.retrieveAll();
    res.send(dataList);
});

The code snippets above is not same as the one in the book overall. But the concept is same. It works fine in my local environment, but I'm wondering isn't there any problem if the request is coming and handled before the data store is imported due that the import function is async operation? Are there other solutions which can fulfill the requirement? Or I'm just missing something that the example from the book is just masterpiece? Thanks in advance!

If you want to guarantee that store has been initialized before any requests are handled by your express app, you could set up the express listener after the load promise has resolved. This would be as simple as the following:

import express from 'express';
import { load, store } from './store.mjs';

const app = express();

app.use('/', (req, res, next) => {
    const dataList = store.retrieveAll();
    res.send(dataList);
});

load()
.then(() => {
   app.listen(port, () => {
     console.log(`Example app listening at http://localhost:${port}`);
   });
})
.catch(err => console.error(`Exception with error: ${err}`));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM