From 83e8d87f3bede87cfff554e7de93658a9095faad Mon Sep 17 00:00:00 2001 From: Dan Goss Date: Fri, 26 Jul 2024 16:16:25 +0100 Subject: [PATCH] WIP [api] adapt configs for ESM, run tests with --experimental-vm-modules enabled, bump ts-jest --- api.planx.uk/README.md | 1 + api.planx.uk/jest.config.ts | 26 +++++++++++++---- api.planx.uk/package.json | 8 +++--- api.planx.uk/pnpm-lock.yaml | 50 +++++++++++++++++++++++++++++---- api.planx.uk/tsconfig.json | 1 + api.planx.uk/tsconfig.test.json | 7 +++++ 6 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 api.planx.uk/tsconfig.test.json diff --git a/api.planx.uk/README.md b/api.planx.uk/README.md index e9adb7dc07..4ebd96be20 100644 --- a/api.planx.uk/README.md +++ b/api.planx.uk/README.md @@ -27,6 +27,7 @@ Development notes: - if you need to test or pull new changes from @opensystemslab/planx-document-templates or @opensystemslab/planx-core, make sure to update the commit hash in package.json first - you can also use `pnpm link {{local relative path to @opensystemslab/planx-document-templates or @opensystemslab/planx-core}}` to manage local development changes these packages without having to reinstall. If you do this, remember to also run `pnpm unlink` to unlink the local directory and then also update the commit hash to point to the most recent version of the package. +- If you want to test particular files directly (e.g. `pnpm jest server.test.js`), note that since we now treat all files as ES modules, you'll need to export `NODE_OPTIONS="--experimental-vm-modules"` the following environment variable (or include it in every such command). ## Prior art diff --git a/api.planx.uk/jest.config.ts b/api.planx.uk/jest.config.ts index e8c198d6a9..72db933719 100644 --- a/api.planx.uk/jest.config.ts +++ b/api.planx.uk/jest.config.ts @@ -1,16 +1,30 @@ -export default { +import type { JestConfigWithTsJest } from "ts-jest"; + +const config: JestConfigWithTsJest = { + // we don't use a preset, preferring to give an explicit manual config testEnvironment: "node", - preset: "ts-jest", transform: { - "^.+\\.js$": [ - "esbuild-jest", + // esbuild-jest is unmaintained and can't handle TypeScript with ESM, so we stick to ts-jest + // TODO: if tests are slow, consider swapping out for @swc/jest + "^.+\\.[jt]s$": [ + "ts-jest", { - sourcemap: true, + useESM: true, + target: "esnext", + // we need a separate moduleResolutuion for tests (jest v30 may fix this) + tsconfig: "tsconfig.test.json", }, ], }, testPathIgnorePatterns: ["dist/*"], setupFilesAfterEnv: ["./jest.setup.js"], + // handle .ts files first, as ESM modules, and remove .js from imports for jest + moduleFileExtensions: ["ts", "js", "json"], + extensionsToTreatAsEsm: [".ts"], + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, + // set up coverage collection collectCoverage: true, coverageThreshold: { global: { @@ -20,3 +34,5 @@ export default { coverageReporters: ["lcov", "text-summary"], coverageDirectory: "./coverage", }; + +export default config; diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index 65ccabb837..7a9e5eff0c 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -56,9 +56,9 @@ "lint": "eslint '**/*.{js,ts}' && prettier -c .", "lint:fix": "eslint --fix '**/*.{js,ts}' && prettier -w .", "check": "tsc --noEmit && pnpm lint", - "test": "TZ=Europe/London jest --silent", - "test:coverage": "TZ=Europe/London jest; open ./coverage/lcov-report/index.html", - "test:watch": "TZ=Europe/London jest --coverage=false --watch", + "test": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest --silent", + "test:coverage": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest; open ./coverage/lcov-report/index.html", + "test:watch": "TZ=Europe/London NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest --coverage=false --watch", "build": "rimraf ./dist && npx tsc && pnpm copy-swagger-files", "prepare": "cd .. && husky install api.planx.uk/.husky", "copy-swagger-files": "copyfiles '**/docs.yaml' dist" @@ -111,7 +111,7 @@ "prettier": "^3.2.4", "rimraf": "^5.0.5", "supertest": "^7.0.0", - "ts-jest": "^29.1.1", + "ts-jest": "^29.2.3", "ts-node-dev": "^2.0.0", "typescript": "^5.5.2", "uuid": "^10.0.0" diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index 7511308019..7de8937d71 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -268,8 +268,8 @@ devDependencies: specifier: ^7.0.0 version: 7.0.0 ts-jest: - specifier: ^29.1.1 - version: 29.1.1(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2) + specifier: ^29.2.3 + version: 29.2.3(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2) ts-node-dev: specifier: ^2.0.0 version: 2.0.0(@types/node@18.19.13)(typescript@5.5.2) @@ -2457,6 +2457,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: true + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -3515,6 +3519,14 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: false + /ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.9.2 + dev: true + /electron-to-chromium@1.5.0: resolution: {integrity: sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==} dev: true @@ -4118,6 +4130,12 @@ packages: dependencies: flat-cache: 3.2.0 + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.6 + dev: true + /filewatcher@3.0.1: resolution: {integrity: sha512-Fro8py2B8EJupSP37Kyd4kjKZLr+5ksFq7Vbw8A392Z15Unq8016SPUDvO/AsDj5V6bbPk98PTAinpc5YhPbJw==} dependencies: @@ -5017,6 +5035,17 @@ packages: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + /jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.5 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + /jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6004,6 +6033,13 @@ packages: dependencies: brace-expansion: 1.1.11 + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -7641,12 +7677,13 @@ packages: hasBin: true dev: true - /ts-jest@29.1.1(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2): - resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + /ts-jest@29.2.3(@babel/core@7.24.0)(esbuild@0.22.0)(jest@29.7.0)(typescript@5.5.2): + resolution: {integrity: sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 '@jest/types': ^29.0.0 babel-jest: ^29.0.0 esbuild: '*' @@ -7655,6 +7692,8 @@ packages: peerDependenciesMeta: '@babel/core': optional: true + '@jest/transform': + optional: true '@jest/types': optional: true babel-jest: @@ -7664,6 +7703,7 @@ packages: dependencies: '@babel/core': 7.24.0 bs-logger: 0.2.6 + ejs: 3.1.10 esbuild: 0.22.0 fast-json-stable-stringify: 2.1.0 jest: 29.7.0(@types/node@18.19.13) diff --git a/api.planx.uk/tsconfig.json b/api.planx.uk/tsconfig.json index 7f18a54313..951eb38659 100644 --- a/api.planx.uk/tsconfig.json +++ b/api.planx.uk/tsconfig.json @@ -1,4 +1,5 @@ { + // as of July 24, esnext == es2022 and nodenext == node16 "compilerOptions": { "allowJs": true, "esModuleInterop": true, diff --git a/api.planx.uk/tsconfig.test.json b/api.planx.uk/tsconfig.test.json new file mode 100644 index 0000000000..ea5b7c77b4 --- /dev/null +++ b/api.planx.uk/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + } +}