Repository: jhipster/jhipster-lite
Pull request #10468 (2024-07-31 21:33:03)

Modernize typescript module
- simpler tsconfig
- setup vitest
- remove jest setup in optional-ts module

Preparation for #10421


Patch:
diff --git a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java
index 13c28395c..ebc478086 100644
--- a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java
@@ -1,11 +1,6 @@
 package tech.jhipster.lite.generator.typescript.core.domain;
 
-import static tech.jhipster.lite.module.domain.JHipsterModule.from;
-import static tech.jhipster.lite.module.domain.JHipsterModule.moduleBuilder;
-import static tech.jhipster.lite.module.domain.JHipsterModule.packageName;
-import static tech.jhipster.lite.module.domain.JHipsterModule.scriptCommand;
-import static tech.jhipster.lite.module.domain.JHipsterModule.scriptKey;
-import static tech.jhipster.lite.module.domain.JHipsterModule.to;
+import static tech.jhipster.lite.module.domain.JHipsterModule.*;
 import static tech.jhipster.lite.module.domain.packagejson.VersionSource.COMMON;
 
 import tech.jhipster.lite.module.domain.JHipsterModule;
@@ -24,19 +19,28 @@ public class TypescriptModuleFactory {
     return moduleBuilder(properties)
       .packageJson()
         .addDevDependency(packageName("typescript"), COMMON)
+        .addDevDependency(packageName("@tsconfig/recommended"), COMMON)
         .addDevDependency(packageName("@typescript-eslint/eslint-plugin"), COMMON)
         .addDevDependency(packageName("@typescript-eslint/parser"), COMMON)
+        .addDevDependency(packageName("@vitest/coverage-istanbul"), COMMON)
         .addDevDependency(packageName("eslint"), COMMON)
         .addDevDependency(packageName("eslint-import-resolver-typescript"), COMMON)
         .addDevDependency(packageName("eslint-plugin-import"), COMMON)
         .addDevDependency(packageName("eslint-plugin-prettier"), COMMON)
-        .addScript(scriptKey("test"), scriptCommand("echo 'Error: no test specified'"))
-        .addScript(scriptKey("eslint:ci"), scriptCommand("eslint './**/*.{ts,js}'"))
-        .addScript(scriptKey("eslint"), scriptCommand("eslint './**/*.{ts,js}' --fix"))
+        .addDevDependency(packageName("vite-tsconfig-paths"), COMMON)
+        .addDevDependency(packageName("vitest"), COMMON)
+        .addDevDependency(packageName("vitest-sonar-reporter"), COMMON)
+        .addScript(scriptKey("lint"), scriptCommand("eslint --ext .js,.ts,.tsx src/"))
+        .addScript(scriptKey("test"), scriptCommand("npm run test:watch"))
+        .addScript(scriptKey("test:coverage"), scriptCommand("vitest run --coverage"))
+        .addScript(scriptKey("test:watch"), scriptCommand("vitest --"))
         .and()
       .files()
-        .add(SOURCE.file(".eslintrc.js"), to(".eslintrc.js"))
-        .add(SOURCE.file("tsconfig.json"), to("tsconfig.json"))
+        .batch(SOURCE, to("."))
+          .addFile("tsconfig.json")
+          .addTemplate("vitest.config.ts")
+          .addFile(".eslintrc.cjs")
+          .and()
         .and()
       .build();
     //@formatter:on
diff --git a/src/main/java/tech/jhipster/lite/generator/typescript/optional/domain/OptionalTypescriptModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/typescript/optional/domain/OptionalTypescriptModuleFactory.java
index 657e97701..3888d11e2 100644
--- a/src/main/java/tech/jhipster/lite/generator/typescript/optional/domain/OptionalTypescriptModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/typescript/optional/domain/OptionalTypescriptModuleFactory.java
@@ -1,38 +1,19 @@
 package tech.jhipster.lite.generator.typescript.optional.domain;
 
-import static tech.jhipster.lite.module.domain.JHipsterModule.from;
-import static tech.jhipster.lite.module.domain.JHipsterModule.moduleBuilder;
-import static tech.jhipster.lite.module.domain.JHipsterModule.packageName;
-import static tech.jhipster.lite.module.domain.JHipsterModule.scriptCommand;
-import static tech.jhipster.lite.module.domain.JHipsterModule.scriptKey;
-import static tech.jhipster.lite.module.domain.JHipsterModule.to;
-import static tech.jhipster.lite.module.domain.packagejson.VersionSource.COMMON;
+import static tech.jhipster.lite.module.domain.JHipsterModule.*;
 
 import tech.jhipster.lite.module.domain.JHipsterModule;
-import tech.jhipster.lite.module.domain.file.JHipsterSource;
 import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
 import tech.jhipster.lite.shared.error.domain.Assert;
 
 public class OptionalTypescriptModuleFactory {
 
-  private static final JHipsterSource SOURCE = from("typescript");
-
   public JHipsterModule buildModule(JHipsterModuleProperties properties) {
     Assert.notNull("properties", properties);
 
     //@formatter:off
     return moduleBuilder(properties)
-      .packageJson()
-        .addDevDependency(packageName("jest"), COMMON)
-        .addDevDependency(packageName("@types/jest"), COMMON)
-        .addDevDependency(packageName("ts-jest"), COMMON)
-        .addScript(scriptKey("jest"), scriptCommand("jest src/test/webapp/unit --logHeapUsage --maxWorkers=2 --no-cache"))
-        .addScript(scriptKey("test"), scriptCommand("npm run jest --"))
-        .addScript(scriptKey("test:watch"), scriptCommand("jest --watch"))
-        .addScript(scriptKey("test:watch:all"), scriptCommand("jest --watchAll"))
-      .and()
       .files()
-        .add(SOURCE.file("jest.config.js"), to("jest.config.js"))
         .add(from("typescript/webapp/common/domain/optional/").file("Optional.ts"), to("src/main/webapp/app/common/domain/Optional.ts"))
         .add(from("typescript/test/webapp/unit/common/domain/optional/").file("Optional.spec.ts"), to("src/test/webapp/unit/common/domain/Optional.spec.ts"))
       .and()
diff --git a/src/main/resources/generator/dependencies/common/package.json b/src/main/resources/generator/dependencies/common/package.json
index 87a7e5846..3f020470c 100644
--- a/src/main/resources/generator/dependencies/common/package.json
+++ b/src/main/resources/generator/dependencies/common/package.json
@@ -7,6 +7,7 @@
     "@babel/cli": "7.24.8",
     "@playwright/test": "1.45.3",
     "@prettier/plugin-xml": "3.4.1",
+    "@tsconfig/recommended": "1.0.7",
     "@types/jest": "29.5.12",
     "@types/node": "20.14.12",
     "@typescript-eslint/eslint-plugin": "7.17.0",
diff --git a/src/main/resources/generator/typescript/.eslintrc.js b/src/main/resources/generator/typescript/.eslintrc.cjs
similarity index 100%
rename from src/main/resources/generator/typescript/.eslintrc.js
rename to src/main/resources/generator/typescript/.eslintrc.cjs
diff --git a/src/main/resources/generator/typescript/tsconfig.json b/src/main/resources/generator/typescript/tsconfig.json
index 847630e24..83bccfee7 100644
--- a/src/main/resources/generator/typescript/tsconfig.json
+++ b/src/main/resources/generator/typescript/tsconfig.json
@@ -1,17 +1,11 @@
 {
+  "extends": "@tsconfig/recommended/tsconfig.json",
   "compilerOptions": {
-    "target": "esnext",
-    "module": "commonjs",
-    "noImplicitAny": true,
-    "removeComments": true,
-    "preserveConstEnums": true,
-    "outFile": "dist/main.js",
-    "sourceMap": true,
+    "types": ["vitest/globals"],
     "baseUrl": ".",
     "paths": {
       "@/*": ["src/main/webapp/app/*"]
     }
   },
-  "include": ["src/**/*"],
-  "exclude": ["node_modules", "**/*.spec.ts"]
+  "include": ["src/main/webapp/**/*", "src/test/webapp/unit/**/*"]
 }


Test patch:
diff --git a/src/main/resources/generator/typescript/vitest.config.ts.mustache b/src/main/resources/generator/typescript/vitest.config.ts.mustache
new file mode 100644
index 000000000..2a0eaee09
--- /dev/null
+++ b/src/main/resources/generator/typescript/vitest.config.ts.mustache
@@ -0,0 +1,47 @@
+/// <reference types="vitest" />
+
+import tsconfigPaths from 'vite-tsconfig-paths';
+import { defineConfig, configDefaults } from 'vitest/config';
+
+export default defineConfig({
+  plugins: [tsconfigPaths()],
+  test: {
+    reporters: ['verbose', 'vitest-sonar-reporter'],
+    outputFile: {
+      'vitest-sonar-reporter': '{{projectBuildDirectory}}/test-results/TESTS-results-sonar.xml',
+    },
+    globals: true,
+    logHeapUsage: true,
+    poolOptions: {
+      threads: {
+        minThreads: 1,
+        maxThreads: 2,
+      },
+    },
+    environment: 'node',
+    cache: false,
+    include: ['src/test/webapp/unit/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
+    coverage: {
+      all: true,
+      thresholds: {
+        perFile: true,
+        autoUpdate: true,
+        100: true,
+      },
+      include: ['src/main/webapp/**/*.ts?(x)'],
+      exclude: [
+        ...configDefaults.coverage.exclude as string[],
+      ],
+      clean: true,
+      provider: 'istanbul',
+      reportsDirectory: '{{projectBuildDirectory}}/test-results/',
+      reporter: ['html', 'json-summary', 'text', 'text-summary', 'lcov', 'clover'],
+      watermarks: {
+        statements: [100, 100],
+        branches: [100, 100],
+        functions: [100, 100],
+        lines: [100, 100],
+      },
+    },
+  },
+});
diff --git a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java
index 1195dd5b8..1c4839fe3 100644
--- a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java
@@ -24,16 +24,22 @@ class TypescriptModuleFactoryTest {
     assertThatModuleWithFiles(module, packageJsonFile())
       .hasFile("package.json")
       .containing(nodeDependency("typescript"))
+      .containing(nodeDependency("@tsconfig/recommended"))
       .containing(nodeDependency("@typescript-eslint/eslint-plugin"))
       .containing(nodeDependency("@typescript-eslint/parser"))
+      .containing(nodeDependency("@vitest/coverage-istanbul"))
       .containing(nodeDependency("eslint"))
       .containing(nodeDependency("eslint-import-resolver-typescript"))
       .containing(nodeDependency("eslint-plugin-import"))
       .containing(nodeDependency("eslint-plugin-prettier"))
-      .containing("\"test\": \"echo 'Error: no test specified'\"")
-      .containing("\"eslint:ci\": \"eslint './**/*.{ts,js}'\"")
-      .containing("\"eslint\": \"eslint './**/*.{ts,js}' --fix\"")
+      .containing(nodeDependency("vite-tsconfig-paths"))
+      .containing(nodeDependency("vitest"))
+      .containing(nodeDependency("vitest-sonar-reporter"))
+      .containing(nodeScript("test", "npm run test:watch"))
+      .containing(nodeScript("test:coverage", "vitest run --coverage"))
+      .containing(nodeScript("test:watch", "vitest --"))
+      .containing(nodeScript("lint", "eslint --ext .js,.ts,.tsx src/"))
       .and()
-      .hasPrefixedFiles("", ".eslintrc.js", "tsconfig.json");
+      .hasPrefixedFiles("", ".eslintrc.cjs", "tsconfig.json");
   }
 }
diff --git a/src/test/java/tech/jhipster/lite/generator/typescript/domain/optional/OptionalTypescriptModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/typescript/domain/optional/OptionalTypescriptModuleFactoryTest.java
index 566e50d57..030b6931f 100644
--- a/src/test/java/tech/jhipster/lite/generator/typescript/domain/optional/OptionalTypescriptModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/typescript/domain/optional/OptionalTypescriptModuleFactoryTest.java
@@ -1,6 +1,6 @@
 package tech.jhipster.lite.generator.typescript.domain.optional;
 
-import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.assertThatModuleWithFiles;
 
 import org.junit.jupiter.api.Test;
 import tech.jhipster.lite.TestFileUtils;
@@ -21,16 +21,7 @@ class OptionalTypescriptModuleFactoryTest {
 
     JHipsterModule module = factory.buildModule(properties);
 
-    assertThatModuleWithFiles(module, packageJsonFile())
-      .hasFile("package.json")
-      .containing(nodeDependency("jest"))
-      .containing(nodeDependency("@types/jest"))
-      .containing(nodeDependency("ts-jest"))
-      .containing("\"jest\": \"jest src/test/webapp/unit --logHeapUsage --maxWorkers=2 --no-cache\"")
-      .containing("\"test\": \"npm run jest --\"")
-      .containing("\"test:watch\": \"jest --watch\"")
-      .containing("\"test:watch:all\": \"jest --watchAll\"")
-      .and()
+    assertThatModuleWithFiles(module)
       .hasFile("src/main/webapp/app/common/domain/Optional.ts")
       .and()
       .hasFile("src/test/webapp/unit/common/domain/Optional.spec.ts");