Skip to content

Commit

Permalink
Merge pull request #669 from pascalgrimaud/vite-vue3-generator
Browse files Browse the repository at this point in the history
generate Vite+Vue3 client
  • Loading branch information
pascalgrimaud authored Feb 12, 2022
2 parents 7391ec7 + f464aa1 commit 54bdb82
Show file tree
Hide file tree
Showing 30 changed files with 780 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package tech.jhipster.lite.generator.client.vite.vue.core.application;

import org.springframework.stereotype.Service;
import tech.jhipster.lite.generator.client.vite.vue.core.domain.ViteVueService;
import tech.jhipster.lite.generator.project.domain.Project;

@Service
public class ViteVueApplicationService {

private final ViteVueService viteVueService;

public ViteVueApplicationService(ViteVueService viteVueService) {
this.viteVueService = viteVueService;
}

public void addViteVue(Project project) {
viteVueService.addViteVue(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tech.jhipster.lite.generator.client.vite.vue.core.domain;

import java.util.List;

public class ViteVue {

private ViteVue() {}

public static List<String> dependencies() {
return List.of("vue", "vue-class-component");
}

public static List<String> devDependencies() {
return List.of(
"@rushstack/eslint-patch",
"@types/jest",
"@typescript-eslint/parser",
"@vitejs/plugin-vue",
"@vue/eslint-config-typescript",
"@vue/test-utils",
"eslint",
"eslint-config-prettier",
"eslint-plugin-vue",
"jest",
"jest-sonar-reporter",
"jest-transform-stub",
"ts-jest",
"typescript",
"vite",
"vue-jest",
"vue-tsc"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package tech.jhipster.lite.generator.client.vite.vue.core.domain;

import static tech.jhipster.lite.common.domain.FileUtils.getPath;
import static tech.jhipster.lite.generator.project.domain.Constants.PACKAGE_JSON;

import java.util.List;
import java.util.Map;
import tech.jhipster.lite.error.domain.GeneratorException;
import tech.jhipster.lite.generator.packagemanager.npm.domain.NpmService;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;

public class ViteVueDomainService implements ViteVueService {

public static final String SOURCE = "client/vite/vue3";

private final ProjectRepository projectRepository;
private final NpmService npmService;

public ViteVueDomainService(ProjectRepository projectRepository, NpmService npmService) {
this.projectRepository = projectRepository;
this.npmService = npmService;
}

@Override
public void addViteVue(Project project) {
addDependencies(project);
addDevDependencies(project);
addScripts(project);
addJestSonar(project);

addViteConfigFiles(project);

addRootFiles(project);
addAppFiles(project);
}

public void addDependencies(Project project) {
ViteVue.dependencies().forEach(dependency -> addDependency(project, dependency));
}

public void addDevDependencies(Project project) {
ViteVue.devDependencies().forEach(devDependency -> addDevDependency(project, devDependency));
}

private void addDependency(Project project, String dependency) {
npmService
.getVersion("vite/vue3", dependency)
.ifPresentOrElse(
version -> npmService.addDependency(project, dependency, version),
() -> {
throw new GeneratorException("Dependency not found: " + dependency);
}
);
}

private void addDevDependency(Project project, String devDependency) {
npmService
.getVersion("vite/vue3", devDependency)
.ifPresentOrElse(
version -> npmService.addDevDependency(project, devDependency, version),
() -> {
throw new GeneratorException("DevDependency not found: " + devDependency);
}
);
}

public void addScripts(Project project) {
// prettier-ignore
Map
.of(
"build", "vue-tsc --noEmit && vite build --emptyOutDir",
"dev", "vite",
"preview", "vite preview",
"test", "jest src/test/javascript/spec"
)
.forEach((name, cmd) -> npmService.addScript(project, name, cmd));
}

public void addViteConfigFiles(Project project) {
List
.of(".eslintrc.js", "jest.config.js", "tsconfig.json", "vite.config.ts")
.forEach(file -> projectRepository.add(project, SOURCE, file));
}

public void addRootFiles(Project project) {
projectRepository.template(project, getPath(SOURCE, "webapp"), "index.html", "src/main/webapp");
projectRepository.template(project, getPath(SOURCE, "webapp/app"), "env.d.ts", "src/main/webapp/app");
projectRepository.template(project, getPath(SOURCE, "webapp/app"), "main.ts", "src/main/webapp/app");

projectRepository.add(
project,
getPath(SOURCE, "webapp/content/images"),
"JHipster-Lite-neon-green.png",
"src/main/webapp/content/images"
);
projectRepository.add(project, getPath(SOURCE, "webapp/content/images"), "logo.png", "src/main/webapp/content/images");
}

public void addAppFiles(Project project) {
String sourcePrimary = getPath(SOURCE, "webapp/app/common/primary/app");
String destinationPrimary = "src/main/webapp/app/common/primary/app";

projectRepository.template(project, sourcePrimary, "App.component.ts", destinationPrimary);
projectRepository.template(project, sourcePrimary, "App.vue", destinationPrimary);
projectRepository.template(project, sourcePrimary, "index.ts", destinationPrimary);

projectRepository.template(
project,
getPath(SOURCE, "test/spec/common/primary/app"),
"App.spec.ts",
"src/test/javascript/spec/common/primary/app"
);
}

public void addJestSonar(Project project) {
String oldText = "\"cacheDirectories\": \\[";
String newText =
"""
"jestSonar": \\{
"reportPath": "target/test-results/jest",
"reportFile": "TESTS-results-sonar.xml"
\\},
"cacheDirectories": \\[""";
projectRepository.replaceText(project, "", PACKAGE_JSON, oldText, newText);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tech.jhipster.lite.generator.client.vite.vue.core.domain;

import tech.jhipster.lite.generator.project.domain.Project;

public interface ViteVueService {
void addViteVue(Project project);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package tech.jhipster.lite.generator.client.vite.vue.core.infrastructure.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.jhipster.lite.generator.client.vite.vue.core.domain.ViteVueDomainService;
import tech.jhipster.lite.generator.client.vite.vue.core.domain.ViteVueService;
import tech.jhipster.lite.generator.packagemanager.npm.domain.NpmService;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;

@Configuration
public class ViteVueBeanConfiguration {

private final ProjectRepository projectRepository;
private final NpmService npmService;

public ViteVueBeanConfiguration(ProjectRepository projectRepository, NpmService npmService) {
this.projectRepository = projectRepository;
this.npmService = npmService;
}

@Bean
public ViteVueService viteVueService() {
return new ViteVueDomainService(projectRepository, npmService);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tech.jhipster.lite.generator.client.vite.vue.core.infrastructure.primary.rest;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.jhipster.lite.generator.client.vite.vue.core.application.ViteVueApplicationService;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.infrastructure.primary.dto.ProjectDTO;
import tech.jhipster.lite.technical.infrastructure.primary.annotation.GeneratorStep;

@RestController
@RequestMapping("/api/vite/vue")
@Tag(name = "Vite - Vue")
class ViveVueResource {

private final ViteVueApplicationService viteVueApplicationService;

public ViveVueResource(ViteVueApplicationService viteVueApplicationService) {
this.viteVueApplicationService = viteVueApplicationService;
}

@Operation(summary = "Add Vite+Vue3", description = "Add Vite+Vue3")
@ApiResponse(responseCode = "500", description = "An error occurred while adding Vite+Vue3")
@PostMapping
@GeneratorStep(id = "vite-vue")
public void addViteVue(@RequestBody ProjectDTO projectDTO) {
Project project = ProjectDTO.toProject(projectDTO);
viteVueApplicationService.addViteVue(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@tech.jhipster.lite.BusinessContext
package tech.jhipster.lite.generator.client.vite.vue.core;
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ public Optional<String> getVersionInCommon(String name) {
return getVersion("common", name);
}

private Optional<String> getVersion(String folderType, String name) {
Assert.notBlank("folderType", folderType);
@Override
public Optional<String> getVersion(String folder, String name) {
Assert.notBlank("folder", folder);
Assert.notBlank("name", name);
return FileUtils
.readLineInClasspath(getPath(TEMPLATE_FOLDER, DEPENDENCIES_FOLDER, folderType, PACKAGE_JSON), DQ + name + DQ)
.readLineInClasspath(getPath(TEMPLATE_FOLDER, DEPENDENCIES_FOLDER, folder, PACKAGE_JSON), DQ + name + DQ)
.map(readValue -> {
String[] result = readValue.split(":");
if (result.length == 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public interface NpmService {
void install(Project project);
void prettify(Project project);

Optional<String> getVersion(String folder, String name);
Optional<String> getVersionInCommon(String name);
}
13 changes: 13 additions & 0 deletions src/main/resources/generator/client/vite/vue3/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
env: {
node: true,
},
extends: ['eslint:recommended', 'plugin:vue/vue3-recommended', '@vue/eslint-config-typescript', 'prettier'],
parserOptions: {
parser: '@typescript-eslint/parser',
},
rules: {
quotes: ['error', 'single', { avoidEscape: true }],
'@typescript-eslint/no-unused-vars': ['error'],
},
};
27 changes: 27 additions & 0 deletions src/main/resources/generator/client/vite/vue3/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
moduleFileExtensions: ['js', 'ts', 'json', 'vue'],
transform: {
'^.+\\.ts$': 'ts-jest',
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|png|jpg|svg|ttf|woff|woff2)$': 'jest-transform-stub',
},
collectCoverage: true,
collectCoverageFrom: [
'src/main/webapp/**/*.{js,ts,vue}',
'!src/main/webapp/**/*.component.ts',
'!src/main/webapp/app/main.ts',
'!**/*.d.ts',
],
coverageReporters: ['html', 'json-summary', 'text-summary', 'lcov', 'clover'],
coverageDirectory: '<rootDir>/target/test-results/',
coverageThreshold: {
global: {
statements: 100,
branches: 100,
functions: 100,
lines: 100,
},
},
modulePathIgnorePatterns: ['<rootDir>/src/main/resources/'],
testResultsProcessor: 'jest-sonar-reporter',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { shallowMount, VueWrapper } from '@vue/test-utils';
import { AppVue } from '../../../../../../main/webapp/app/common/primary/app';

let wrapper: VueWrapper;

const wrap = () => {
wrapper = shallowMount(AppVue);
};

describe('App', () => {
it('should exist', () => {
wrap();
expect(wrapper.exists()).toBe(true);
});
});
17 changes: 17 additions & 0 deletions src/main/resources/generator/client/vite/vue3/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"types": ["vite/client", "@types/jest"]
},
"include": ["src/main/webapp/**/*.ts", "src/main/webapp/**/*.d.ts", "src/main/webapp/**/*.tsx", "src/main/webapp/**/*.vue"],
"exclude": ["./node_modules"]
}
19 changes: 19 additions & 0 deletions src/main/resources/generator/client/vite/vue3/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: tag => /^x-/.test(tag),
},
},
}),
],
build: {
outDir: '../../../target/classes/static',
},
root: 'src/main/webapp',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Vue } from 'vue-class-component';

export default class App extends Vue {}
Loading

0 comments on commit 54bdb82

Please sign in to comment.