简体   繁体   中英

Hot reloading with typescript and node

A lot of articles exist out there explaining how to hook up nodemon or ts-node-dev to automatically restart your TypeScript server on file changes, but restarting the whole server is starting to get pretty slow on my large TypeScript project, where startup times can take many tens of seconds (thanks typeorm ).

Frontend development has been dominated by boilerplates like create-react-app , nextjs and more that offer hot reloading without even a page refresh, resulting in very fast feedback times for frontend changes.

What's the equivalent for doing that on a Node API, especially one where the source files are in TypeScript, not JS? Should I be using tsc --watch and then invalidating require.cache as compiled output completes or something?

We use

/* eslint-env node */

import path from 'path';

import {
  disposeOnReload,
  enableHotReload,
  getReloadCount,
  hotClass,
  hotRequire,
  hotRequireExportedFn,
  registerUpdateReconciler
} from '@hediet/node-reload';
import { IStart, Logger } from './interfaces';
import { initNextJs } from './modules/application/initNextJs';
import { Globals } from './global';

const index = path.join(__dirname, '../client/index.html');

enableHotReload({ entryModule: module, loggingEnabled: false });
registerUpdateReconciler(module);

Logger.log('[ADMIN] Globals.init()');
Globals.init();

@hotClass(module)
class Loader {
  private v1 = 1; // for reload

  static start(info: IStart) {
    return new Promise<void>((done) =>
      hotRequire<typeof import('./server')>(module, './server', (server) => {
        Logger.log('[ADMIN] server.start()');
        server
          .start(info)
          .then(() => {
            done();
          })
          .catch((error) => {
            Logger.error('[ADMIN] Error starting!', { error });
            process.exit(1);
          });
        return {
          dispose: () => {
            Logger.log('[ADMIN] server.stop()');
            server.stop();
          }
        };
      })
    );
  }
}

let startInfo: IStart;
hotRequireExportedFn(module, Loader, { hasFnChanged: 'useSource' }, (loader) => {
  const reloadCount = getReloadCount(module);
  if (reloadCount === 0) {
    Logger.log('[ADMIN] initNextJs');
    const nextApp = initNextJs(true);
    console.time('************************************************** Prepared Next');
    const preparing = nextApp.prepare().then(() => {
      console.timeEnd('************************************************** Prepared Next');
    });
    startInfo = { nextApp, index, preparing };
  }
  setTimeout(() => loader.start(startInfo), 0);
  return { dispose: () => console.log('loader.dispose()') };
});```

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