Skip to content

Node Typescript Preparations

Wilson Wong edited this page Jan 16, 2025 · 1 revision

Required Changes for Native Node Typescript Execution

Currently (Jan. 15, 2025), the application backend compiles Typescript into Javascript using the ts-node library for deployments. However, NodeJS is starting to implement native Typescript execution and `ts-node will no longer be required in the future. Due to the requirements of NodeJS's implementation, certain changes to configuration and import statements will be required. Due to the current experimental status of native Typescript implementation, switching to it will be postponed until the feature enters LTS status.

This page documents several steps that be required for native Typescript execution for the backend. Please note that jest testing is not operational and requires additional work due to import.meta not being available. Also more configuration work is needed for openshift deployments and is not included here.

Configuration Changes

tsconfig.json

Changes to the following tsconfig values will be required:

  • "module": "nodenext"
  • "noEmit": true
  • "allowImportingTsExtensions": true

package.json

Add the following key-value to the top level of package.json:

  • "type": "module"

File extension changes

Rename the following files with the new file extensions:

  • in app/bin rename the file www to www.ts
  • in app rename jest.config.js to jest.config.cjs
  • in app rename .eslintrc.js to .eslintrc.cjs

Or consider updating to ESM type files, if available.

Replace CommonJS modules with Node ESM modules

The following files are using Node CJS modules (in the form of module.<something> or __dirname). You will need to replace them with the appropriate ES modules.

  • app.ts
  • log.ts
  • log.spec.ts
  • knexfile.ts
  • utils.ts
  • www.ts

Replace module.filename with __filename after adding the following lines:

import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);

Add the following lines to enable __dirname to function to the appropriate files:

import path from 'path';
const __dirname = path.dirname(__filename);

Add file extensions to import statements

Non-json related imports

Due to Node's planned typescript execution implementation, all non-library import statements will require file extensions. Use the following regex to find and add file extensions to the majority of files. A suggestion is to limit replacements to ./app. The regex is to be used with VSCode. There may be a better regex, but the following procedure is a multi-step regex find and replace.

Start by regex searching with the following regex to handle imports starting with ./:

import(?:["'\s]*([\w*{}\n\r\t, ]+)\s)from\s*?["'](.\/\w.*)';

With the replacement statement:

import $1 from '$2.ts'

Then replace imports starting with ../:

import(?:["'\s]*([\w*{}\n\r\t, ]+)\s)from\s*?["'](..\/\w.*)';

With the replacement statement:

import $1 from '$2.ts'

Next, services and type imports will need to be updated to add in their index.ts files.

Replace /services.ts with /services/index.ts

Replace /types.ts with /types/index.ts

JSON related imports

As named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to 'NodeNext' and import attributes are required for JSON imports, there needs to be a manual update. This section assumes the non-JSON imports has been completed.

Currently only app.ts has an import for package.json, but please check if other imports have occurred.

Named imports suchs as:

import { name as appName } from './package.json';

Are no longer supported, a singular import is required. Type annotations for JSON are now mandatory. The prior line should be updated with the following:

import jsonPackage from './package.json' with { type: 'json' };

And update the file that previously relied on appName or similar destructured values in the rest of the file as needed.