Reputation: 309
In my node backend, I have the following file structure:
project
|-- expensive
| |-- index.ts
|-- files
| |-- foo.ts
| |-- bar.ts
| `-- baz.ts
|-- tsconfig.json
|-- package.json
`-- index.ts
I want to reload only part of my project (./files/*
) without having to restart the entire thing.
What I did was use dynamic import:
// inside index.ts...
const client = new Client() as Client;
client.expensive = new Map();
client.files = new Map()
// load each file under the `files` dir
client.loadFiles = async () => {
const fileNames = readdirSync('./files/')
fileNames.forEach(async name => {
const module = await import('./files/' + name); // dynamic import
client.files.set(module.default.name, module.default)
})
}
// client.loadExpensive...
// load everything
async function loadAll(reload: boolean = false) {
await client.loadFiles(reload);
await client.loadExpensive(reload);
}
loadAll();
startApp();
Then the reload function would be:
// reload all or the specified dir
client.reload = async (dir?: string | undefined) => {
if (dir) {
dir = dir.replace(/^\w/, c => c.toUpperCase()); // capitalize
if (client.hasOwnProperty('load'+dir)) client['load'+dir]();
else console.error('no such dir')
} else {
await loadAll();
}
}
Problem is while the project loads and reload without error.
Adding or removing files under .files/*
, then calling .reload()
does not seem produce any change. Why is that?
Prior to converting to TS, I used require and cache busting:
// additional reload arg
client.loadFiles = async (reload) => {
const fileNames = readdirSync('./files/')
fileNames.forEach(async name => {
// delete require cache then require the file
if (reload) delete require.cache[require.resolve(`./${dir}/${name}.ts`)];
client.files.set(module.default.name, module.default)
})
}
So i looked at the transpiled js code, it looks like import()
use require underneath.
const module = yield Promise.resolve().then(() => __importStar(require('./files/' + name)));
What am I doing wrong? or is this even a good pattern to follow.
Upvotes: 0
Views: 800
Reputation: 14128
Because import()
compiles to require()
(roughly), you'll need to delete the require cache like you did before you used TS.
client.loadFiles = async (reload: boolean) => {
const fileNames = readdirSync('./files/')
fileNames.forEach(async name => {
// Note that if you're using ts-node the extension will be ts not js
if (reload) delete require.cache[require.resolve(`./files/${name}.js`)]
const module = await import('./files/' + name); // dynamic import
client.files.set(module.default.name, module.default)
})
}
Upvotes: 1