From faae4b30492069826eb01c603ca030b36c87f10c Mon Sep 17 00:00:00 2001 From: Oliver Yasuna Date: Mon, 10 Jun 2024 21:10:30 -0400 Subject: [PATCH 1/9] feat: Add support for customizable `projectFileExtensions`. Fixes #19527 --- .../gradle/VaadinFlowPluginExtension.kt | 11 +++++++++ .../plugin/maven/FlowModeAbstractMojo.java | 13 +++++++++++ .../flow/plugin/base/BuildFrontendUtil.java | 6 +++-- .../flow/plugin/base/PluginAdapterBase.java | 7 ++++++ .../vaadin/flow/server/frontend/Options.java | 23 +++++++++++++++++++ .../flow/server/frontend/TaskUpdateVite.java | 6 ++++- .../src/main/resources/vite.generated.ts | 2 +- 7 files changed, 64 insertions(+), 4 deletions(-) diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index 0924369e56c..1710b34d8e5 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -282,6 +282,13 @@ public abstract class VaadinFlowPluginExtension @Inject constructor(private val public abstract val applicationIdentifier: Property + /** + * The list of file extensions that are considered project files. + * Hashes are calculated for these files as part of detecting if a new prod + * bundle should be generated. + */ + public abstract val projectFileExtensions: ListProperty + public fun filterClasspath(@DelegatesTo(value = ClasspathFilter::class, strategy = Closure.DELEGATE_FIRST) block: Closure<*>) { block.delegate = classpathFilter block.resolveStrategy = Closure.DELEGATE_FIRST @@ -439,6 +446,9 @@ public class PluginEffectiveConfiguration( )) .overrideWithSystemProperty("vaadin.${InitParameters.APPLICATION_IDENTIFIER}") + public val projectFileExtensions: ListProperty = extension.projectFileExtensions + .convention(listOf(".js", ".js.map", ".ts", ".ts.map", ".tsx", ".tsx.map", ".css", ".css.map")) + /** * Finds the value of a boolean property. It searches in gradle and system properties. * @@ -500,6 +510,7 @@ public class PluginEffectiveConfiguration( "frontendHotdeploy=${frontendHotdeploy.get()}," + "reactEnable=${reactEnable.get()}," + "cleanFrontendFiles=${cleanFrontendFiles.get()}" + + "projectFileExtensions=${projectFileExtensions.get()}" + ")" public companion object { public fun get(project: Project): PluginEffectiveConfiguration = diff --git a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java index ae3b389c61f..1d0a6e46b0a 100644 --- a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java +++ b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java @@ -234,6 +234,9 @@ public abstract class FlowModeAbstractMojo extends AbstractMojo @Parameter(property = InitParameters.REACT_ENABLE, defaultValue = "${null}") private Boolean reactEnable; + @Parameter(defaultValue = "${null}") + private List projectFileExtensions; + /** * Identifier for the application. *

@@ -570,4 +573,14 @@ public String applicationIdentifier() { project.getGroupId() + ":" + project.getArtifactId(), StandardCharsets.UTF_8); } + + @Override + public List projectFileExtensions() { + if(projectFileExtensions != null) { + return projectFileExtensions; + } + + return List.of(".js", ".js.map", ".ts", ".ts.map", ".tsx", ".tsx.map", ".css", ".css.map"); + } + } diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index afd1511c7cb..73d729b0049 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -165,7 +165,8 @@ public static void prepareFrontend(PluginAdapterBase adapter) .setNodeAutoUpdate(adapter.nodeAutoUpdate()) .withHomeNodeExecRequired(adapter.requireHomeNodeExec()) .setJavaResourceFolder(adapter.javaResourceFolder()) - .withProductionMode(false).withReact(adapter.isReactEnabled()); + .withProductionMode(false).withReact(adapter.isReactEnabled()) + .withProjectFileExtensions(adapter.projectFileExtensions()); // Copy jar artifact contents in TaskCopyFrontendFiles options.copyResources(adapter.getJarFiles()); @@ -405,7 +406,8 @@ public static void runDevBuildNodeUpdater(PluginAdapterBuild adapter) .withBundleBuild(true) .skipDevBundleBuild(adapter.skipDevBundleBuild()) .withCompressBundle(adapter.compressBundle()) - .withReact(adapter.isReactEnabled()); + .withReact(adapter.isReactEnabled()) + .withProjectFileExtensions(adapter.projectFileExtensions()); new NodeTasks(options).execute(); } catch (ExecutionFailedException exception) { throw exception; diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java index 2a3186651ad..100a053f946 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java @@ -337,4 +337,11 @@ default Lookup createLookup(ClassFinder classFinder) { * {@literal blank}. */ String applicationIdentifier(); + + /** + * Get the list of project file extensions. + * + * @return list of project file extensions + */ + List projectFileExtensions(); } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java index db72b6a31bb..910ff13c5d5 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java @@ -84,6 +84,8 @@ public class Options implements Serializable { private boolean compressBundle = true; + private List projectFileExtensions = null; + /** * The node.js version to be used when node.js is installed automatically by * Vaadin, for example "v16.0.0". Defaults to @@ -967,4 +969,25 @@ public Options withCleanOldGeneratedFiles(boolean clean) { public boolean isCleanOldGeneratedFiles() { return cleanOldGeneratedFiles; } + + /** + * Sets the project file extensions. + * + * @param projectFileExtensions + * the project file extensions + * @return this builder + */ + public Options withProjectFileExtensions(List projectFileExtensions) { + this.projectFileExtensions = projectFileExtensions; + return this; + } + + /** + * Gets the project file extensions. + * + * @return the project file extensions + */ + public List getProjectFileExtensions() { + return projectFileExtensions; + } } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index e76b2e62f3d..7244d397cb1 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -127,7 +127,11 @@ private void createGeneratedConfig() throws IOException { .replace("#webComponentTags#", webComponentTags == null || webComponentTags.isEmpty() ? "" - : String.join(";", webComponentTags)); + : String.join(";", webComponentTags)) + .replace("#projectFileExtensions#", + options.getProjectFileExtensions().stream() + .map(ext -> "'" + ext + "'") + .reduce((a, b) -> a + ", " + b).orElse("")); template = updateFileSystemRouterVitePlugin(template); FileIOUtils.writeIfChanged(generatedConfigFile, template); diff --git a/flow-server/src/main/resources/vite.generated.ts b/flow-server/src/main/resources/vite.generated.ts index c5e59f6f726..0c1a985cc80 100644 --- a/flow-server/src/main/resources/vite.generated.ts +++ b/flow-server/src/main/resources/vite.generated.ts @@ -298,7 +298,7 @@ function statsExtracterPlugin(): PluginOption { const frontendFiles: Record = {}; - const projectFileExtensions = ['.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map']; + const projectFileExtensions = [#projectFileExtensions#]; const isThemeComponentsResource = (id: string) => id.startsWith(themeOptions.frontendGeneratedFolder.replace(/\\/g, '/')) From d153a6fc8112ca90d27915e7e12956e5b7928df7 Mon Sep 17 00:00:00 2001 From: Oliver Yasuna Date: Mon, 24 Jun 2024 09:11:05 -0400 Subject: [PATCH 2/9] Made `projectFileExtensions` into `extraProjectFileExtensions`, which add to existing ones. --- .../vaadin/gradle/VaadinFlowPluginExtension.kt | 9 ++++++--- .../plugin/maven/FlowModeAbstractMojo.java | 11 ++++++----- .../flow/plugin/base/BuildFrontendUtil.java | 4 ++-- .../flow/plugin/base/PluginAdapterBase.java | 2 +- .../vaadin/flow/server/frontend/Options.java | 14 +++++++------- .../flow/server/frontend/TaskUpdateVite.java | 18 ++++++++++++++---- .../src/main/resources/vite.generated.ts | 2 +- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index 1710b34d8e5..caa41987df7 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -283,11 +283,11 @@ public abstract class VaadinFlowPluginExtension @Inject constructor(private val public abstract val applicationIdentifier: Property /** - * The list of file extensions that are considered project files. + * The list of extra file extensions that are considered project files. * Hashes are calculated for these files as part of detecting if a new prod * bundle should be generated. */ - public abstract val projectFileExtensions: ListProperty + public abstract val extraProjectFileExtensions: ListProperty public fun filterClasspath(@DelegatesTo(value = ClasspathFilter::class, strategy = Closure.DELEGATE_FIRST) block: Closure<*>) { block.delegate = classpathFilter @@ -449,6 +449,9 @@ public class PluginEffectiveConfiguration( public val projectFileExtensions: ListProperty = extension.projectFileExtensions .convention(listOf(".js", ".js.map", ".ts", ".ts.map", ".tsx", ".tsx.map", ".css", ".css.map")) + public val extraProjectFileExtensions: ListProperty = extension.extraProjectFileExtensions + .convention(emptyList()) + /** * Finds the value of a boolean property. It searches in gradle and system properties. * @@ -510,7 +513,7 @@ public class PluginEffectiveConfiguration( "frontendHotdeploy=${frontendHotdeploy.get()}," + "reactEnable=${reactEnable.get()}," + "cleanFrontendFiles=${cleanFrontendFiles.get()}" + - "projectFileExtensions=${projectFileExtensions.get()}" + + "extraProjectFileExtensions=${extraProjectFileExtensions.get()}" + ")" public companion object { public fun get(project: Project): PluginEffectiveConfiguration = diff --git a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java index 1d0a6e46b0a..3c60269d4f5 100644 --- a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java +++ b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.function.Function; @@ -235,7 +236,7 @@ public abstract class FlowModeAbstractMojo extends AbstractMojo private Boolean reactEnable; @Parameter(defaultValue = "${null}") - private List projectFileExtensions; + private List extraProjectFileExtensions; /** * Identifier for the application. @@ -575,12 +576,12 @@ public String applicationIdentifier() { } @Override - public List projectFileExtensions() { - if(projectFileExtensions != null) { - return projectFileExtensions; + public List extraProjectFileExtensions() { + if(extraProjectFileExtensions != null) { + return extraProjectFileExtensions; } - return List.of(".js", ".js.map", ".ts", ".ts.map", ".tsx", ".tsx.map", ".css", ".css.map"); + return Collections.emptyList(); } } diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index 73d729b0049..537459dc3b2 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -166,7 +166,7 @@ public static void prepareFrontend(PluginAdapterBase adapter) .withHomeNodeExecRequired(adapter.requireHomeNodeExec()) .setJavaResourceFolder(adapter.javaResourceFolder()) .withProductionMode(false).withReact(adapter.isReactEnabled()) - .withProjectFileExtensions(adapter.projectFileExtensions()); + .withExtraProjectFileExtensions(adapter.extraProjectFileExtensions()); // Copy jar artifact contents in TaskCopyFrontendFiles options.copyResources(adapter.getJarFiles()); @@ -407,7 +407,7 @@ public static void runDevBuildNodeUpdater(PluginAdapterBuild adapter) .skipDevBundleBuild(adapter.skipDevBundleBuild()) .withCompressBundle(adapter.compressBundle()) .withReact(adapter.isReactEnabled()) - .withProjectFileExtensions(adapter.projectFileExtensions()); + .withExtraProjectFileExtensions(adapter.extraProjectFileExtensions()); new NodeTasks(options).execute(); } catch (ExecutionFailedException exception) { throw exception; diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java index 100a053f946..38e9cab1b31 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java @@ -343,5 +343,5 @@ default Lookup createLookup(ClassFinder classFinder) { * * @return list of project file extensions */ - List projectFileExtensions(); + List extraProjectFileExtensions(); } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java index 910ff13c5d5..b062bcfdea6 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java @@ -84,7 +84,7 @@ public class Options implements Serializable { private boolean compressBundle = true; - private List projectFileExtensions = null; + private List extraProjectFileExtensions = null; /** * The node.js version to be used when node.js is installed automatically by @@ -971,14 +971,14 @@ public boolean isCleanOldGeneratedFiles() { } /** - * Sets the project file extensions. + * Sets the extra project file extensions. * - * @param projectFileExtensions + * @param extraProjectFileExtensions * the project file extensions * @return this builder */ - public Options withProjectFileExtensions(List projectFileExtensions) { - this.projectFileExtensions = projectFileExtensions; + public Options withExtraProjectFileExtensions(List extraProjectFileExtensions) { + this.extraProjectFileExtensions = extraProjectFileExtensions; return this; } @@ -987,7 +987,7 @@ public Options withProjectFileExtensions(List projectFileExtensions) { * * @return the project file extensions */ - public List getProjectFileExtensions() { - return projectFileExtensions; + public List getExtraProjectFileExtensions() { + return extraProjectFileExtensions; } } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 7244d397cb1..1c353e30c23 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -22,10 +22,14 @@ import java.io.UncheckedIOException; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.atmosphere.util.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -128,10 +132,16 @@ private void createGeneratedConfig() throws IOException { webComponentTags == null || webComponentTags.isEmpty() ? "" : String.join(";", webComponentTags)) - .replace("#projectFileExtensions#", - options.getProjectFileExtensions().stream() - .map(ext -> "'" + ext + "'") - .reduce((a, b) -> a + ", " + b).orElse("")); + .replace("#extraProjectFileExtensions#", + Optional.ofNullable(options.getExtraProjectFileExtensions()).orElse(Collections.emptyList()).stream() + .map(ext -> { + try { + return "'" + StringEscapeUtils.escapeJava(ext) + "'"; + } catch(Exception e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.joining(", "))); template = updateFileSystemRouterVitePlugin(template); FileIOUtils.writeIfChanged(generatedConfigFile, template); diff --git a/flow-server/src/main/resources/vite.generated.ts b/flow-server/src/main/resources/vite.generated.ts index 0c1a985cc80..94390bc127f 100644 --- a/flow-server/src/main/resources/vite.generated.ts +++ b/flow-server/src/main/resources/vite.generated.ts @@ -298,7 +298,7 @@ function statsExtracterPlugin(): PluginOption { const frontendFiles: Record = {}; - const projectFileExtensions = [#projectFileExtensions#]; + const projectFileExtensions = ['.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map'#extraProjectFileExtensions#]; const isThemeComponentsResource = (id: string) => id.startsWith(themeOptions.frontendGeneratedFolder.replace(/\\/g, '/')) From 1f548d959985799d3114e5464ee76b8e95aa102e Mon Sep 17 00:00:00 2001 From: Oliver Yasuna Date: Mon, 24 Jun 2024 09:12:26 -0400 Subject: [PATCH 3/9] Ran Maven formatter. --- .../plugin/maven/FlowModeAbstractMojo.java | 2 +- .../flow/plugin/base/BuildFrontendUtil.java | 6 ++++-- .../vaadin/flow/server/frontend/Options.java | 3 ++- .../flow/server/frontend/TaskUpdateVite.java | 20 +++++++++---------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java index 3c60269d4f5..50e69d30881 100644 --- a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java +++ b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java @@ -577,7 +577,7 @@ public String applicationIdentifier() { @Override public List extraProjectFileExtensions() { - if(extraProjectFileExtensions != null) { + if (extraProjectFileExtensions != null) { return extraProjectFileExtensions; } diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index 537459dc3b2..7090b0c0418 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -166,7 +166,8 @@ public static void prepareFrontend(PluginAdapterBase adapter) .withHomeNodeExecRequired(adapter.requireHomeNodeExec()) .setJavaResourceFolder(adapter.javaResourceFolder()) .withProductionMode(false).withReact(adapter.isReactEnabled()) - .withExtraProjectFileExtensions(adapter.extraProjectFileExtensions()); + .withExtraProjectFileExtensions( + adapter.extraProjectFileExtensions()); // Copy jar artifact contents in TaskCopyFrontendFiles options.copyResources(adapter.getJarFiles()); @@ -407,7 +408,8 @@ public static void runDevBuildNodeUpdater(PluginAdapterBuild adapter) .skipDevBundleBuild(adapter.skipDevBundleBuild()) .withCompressBundle(adapter.compressBundle()) .withReact(adapter.isReactEnabled()) - .withExtraProjectFileExtensions(adapter.extraProjectFileExtensions()); + .withExtraProjectFileExtensions( + adapter.extraProjectFileExtensions()); new NodeTasks(options).execute(); } catch (ExecutionFailedException exception) { throw exception; diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java index b062bcfdea6..e55a974f28c 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java @@ -977,7 +977,8 @@ public boolean isCleanOldGeneratedFiles() { * the project file extensions * @return this builder */ - public Options withExtraProjectFileExtensions(List extraProjectFileExtensions) { + public Options withExtraProjectFileExtensions( + List extraProjectFileExtensions) { this.extraProjectFileExtensions = extraProjectFileExtensions; return this; } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 1c353e30c23..8bf2ff7a30a 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -132,16 +132,16 @@ private void createGeneratedConfig() throws IOException { webComponentTags == null || webComponentTags.isEmpty() ? "" : String.join(";", webComponentTags)) - .replace("#extraProjectFileExtensions#", - Optional.ofNullable(options.getExtraProjectFileExtensions()).orElse(Collections.emptyList()).stream() - .map(ext -> { - try { - return "'" + StringEscapeUtils.escapeJava(ext) + "'"; - } catch(Exception e) { - throw new RuntimeException(e); - } - }) - .collect(Collectors.joining(", "))); + .replace("#extraProjectFileExtensions#", Optional + .ofNullable(options.getExtraProjectFileExtensions()) + .orElse(Collections.emptyList()).stream().map(ext -> { + try { + return "'" + StringEscapeUtils.escapeJava(ext) + + "'"; + } catch (Exception e) { + throw new RuntimeException(e); + } + }).collect(Collectors.joining(", "))); template = updateFileSystemRouterVitePlugin(template); FileIOUtils.writeIfChanged(generatedConfigFile, template); From ab78bf83e1e6d6dc06eb33e652719409d21cbb08 Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Mon, 4 Nov 2024 14:30:26 +0200 Subject: [PATCH 4/9] Rename, add javadoc examples, add test. --- .../flow/plugin/maven/BuildDevBundleMojo.java | 6 +++++ .../com/vaadin/gradle/GradlePluginAdapter.kt | 3 +++ .../gradle/VaadinFlowPluginExtension.kt | 10 ++++---- .../plugin/maven/FlowModeAbstractMojo.java | 24 +++++++++++++++---- .../flow/plugin/base/BuildFrontendUtil.java | 8 +++---- .../flow/plugin/base/PluginAdapterBase.java | 5 +++- .../vaadin/flow/server/InitParameters.java | 1 + .../vaadin/flow/server/frontend/Options.java | 18 +++++++------- .../flow/server/frontend/TaskUpdateVite.java | 17 +++++-------- .../src/main/resources/vite.generated.ts | 2 +- .../server/frontend/TaskUpdateViteTest.java | 24 +++++++++++++++++++ .../vite-embedded-webcomponent-resync/pom.xml | 6 +++++ 12 files changed, 87 insertions(+), 37 deletions(-) diff --git a/flow-plugins/flow-dev-bundle-plugin/src/main/java/com/vaadin/flow/plugin/maven/BuildDevBundleMojo.java b/flow-plugins/flow-dev-bundle-plugin/src/main/java/com/vaadin/flow/plugin/maven/BuildDevBundleMojo.java index b6562f494ab..dbe8422b124 100644 --- a/flow-plugins/flow-dev-bundle-plugin/src/main/java/com/vaadin/flow/plugin/maven/BuildDevBundleMojo.java +++ b/flow-plugins/flow-dev-bundle-plugin/src/main/java/com/vaadin/flow/plugin/maven/BuildDevBundleMojo.java @@ -21,6 +21,7 @@ import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.function.Consumer; @@ -464,6 +465,11 @@ public String applicationIdentifier() { return project.getGroupId() + ":" + project.getArtifactId(); } + @Override + public List frontendExtraFileExtensions() { + return Collections.emptyList(); + } + @Override public boolean checkRuntimeDependency(String groupId, String artifactId, Consumer missingDependencyMessageConsumer) { diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/GradlePluginAdapter.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/GradlePluginAdapter.kt index 977572330ad..613b3a71a2b 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/GradlePluginAdapter.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/GradlePluginAdapter.kt @@ -239,4 +239,7 @@ internal class GradlePluginAdapter( } return dependencyAbsent } + + override fun frontendExtraFileExtensions(): List = + config.frontendExtraFileExtensions.get() } diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index caa41987df7..75e6420d242 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -287,7 +287,7 @@ public abstract class VaadinFlowPluginExtension @Inject constructor(private val * Hashes are calculated for these files as part of detecting if a new prod * bundle should be generated. */ - public abstract val extraProjectFileExtensions: ListProperty + public abstract val frontendExtraFileExtensions: ListProperty public fun filterClasspath(@DelegatesTo(value = ClasspathFilter::class, strategy = Closure.DELEGATE_FIRST) block: Closure<*>) { block.delegate = classpathFilter @@ -446,10 +446,8 @@ public class PluginEffectiveConfiguration( )) .overrideWithSystemProperty("vaadin.${InitParameters.APPLICATION_IDENTIFIER}") - public val projectFileExtensions: ListProperty = extension.projectFileExtensions - .convention(listOf(".js", ".js.map", ".ts", ".ts.map", ".tsx", ".tsx.map", ".css", ".css.map")) - - public val extraProjectFileExtensions: ListProperty = extension.extraProjectFileExtensions + // TODO: Possibly get value from system param InitParameters.FRONTEND_EXTRA_EXTENSIONS + public val frontendExtraFileExtensions: ListProperty = extension.frontendExtraFileExtensions .convention(emptyList()) /** @@ -513,7 +511,7 @@ public class PluginEffectiveConfiguration( "frontendHotdeploy=${frontendHotdeploy.get()}," + "reactEnable=${reactEnable.get()}," + "cleanFrontendFiles=${cleanFrontendFiles.get()}" + - "extraProjectFileExtensions=${extraProjectFileExtensions.get()}" + + "frontendExtraFileExtensions=${frontendExtraFileExtensions.get()}" + ")" public companion object { public fun get(project: Project): PluginEffectiveConfiguration = diff --git a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java index 50e69d30881..b379805621f 100644 --- a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java +++ b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java @@ -235,8 +235,22 @@ public abstract class FlowModeAbstractMojo extends AbstractMojo @Parameter(property = InitParameters.REACT_ENABLE, defaultValue = "${null}") private Boolean reactEnable; - @Parameter(defaultValue = "${null}") - private List extraProjectFileExtensions; + /** + * Parameter for adding file extensions to handle during frontend tasks. + *

+ * From the commandline use space separated list + * {@code -DfrontendExtraFileExtensions="svg ico"} + *

+ *

+ * In plugin configuration + * + * svg + * ico + * + * + */ + @Parameter(property = InitParameters.FRONTEND_EXTRA_EXTENSIONS, defaultValue = "${null}") + private List frontendExtraFileExtensions; /** * Identifier for the application. @@ -576,9 +590,9 @@ public String applicationIdentifier() { } @Override - public List extraProjectFileExtensions() { - if (extraProjectFileExtensions != null) { - return extraProjectFileExtensions; + public List frontendExtraFileExtensions() { + if (frontendExtraFileExtensions != null) { + return frontendExtraFileExtensions; } return Collections.emptyList(); diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index 7090b0c0418..94f0b6b3236 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -166,8 +166,8 @@ public static void prepareFrontend(PluginAdapterBase adapter) .withHomeNodeExecRequired(adapter.requireHomeNodeExec()) .setJavaResourceFolder(adapter.javaResourceFolder()) .withProductionMode(false).withReact(adapter.isReactEnabled()) - .withExtraProjectFileExtensions( - adapter.extraProjectFileExtensions()); + .withExtraFrontendFileExtensions( + adapter.frontendExtraFileExtensions()); // Copy jar artifact contents in TaskCopyFrontendFiles options.copyResources(adapter.getJarFiles()); @@ -408,8 +408,8 @@ public static void runDevBuildNodeUpdater(PluginAdapterBuild adapter) .skipDevBundleBuild(adapter.skipDevBundleBuild()) .withCompressBundle(adapter.compressBundle()) .withReact(adapter.isReactEnabled()) - .withExtraProjectFileExtensions( - adapter.extraProjectFileExtensions()); + .withExtraFrontendFileExtensions( + adapter.frontendExtraFileExtensions()); new NodeTasks(options).execute(); } catch (ExecutionFailedException exception) { throw exception; diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java index 38e9cab1b31..2538fcfcc3a 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/PluginAdapterBase.java @@ -340,8 +340,11 @@ default Lookup createLookup(ClassFinder classFinder) { /** * Get the list of project file extensions. + *

+ * File extensions are given with or without . prefix eg "png" and ".png" + * are both accepted. * * @return list of project file extensions */ - List extraProjectFileExtensions(); + List frontendExtraFileExtensions(); } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java b/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java index a9889197a45..be19d6435c2 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java @@ -285,4 +285,5 @@ public class InitParameters implements Serializable { */ public static final String APPLICATION_IDENTIFIER = "applicationIdentifier"; + public static final String FRONTEND_EXTRA_EXTENSIONS = "frontendExtraFileExtensions"; } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java index e55a974f28c..c4b25be2761 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java @@ -84,7 +84,7 @@ public class Options implements Serializable { private boolean compressBundle = true; - private List extraProjectFileExtensions = null; + private List frontendExtraFileExtensions = null; /** * The node.js version to be used when node.js is installed automatically by @@ -971,15 +971,15 @@ public boolean isCleanOldGeneratedFiles() { } /** - * Sets the extra project file extensions. + * Sets the extra file extensions used in the project. * - * @param extraProjectFileExtensions - * the project file extensions + * @param frontendExtraFileExtensions + * the file extensions to add for the project * @return this builder */ - public Options withExtraProjectFileExtensions( - List extraProjectFileExtensions) { - this.extraProjectFileExtensions = extraProjectFileExtensions; + public Options withExtraFrontendFileExtensions( + List frontendExtraFileExtensions) { + this.frontendExtraFileExtensions = frontendExtraFileExtensions; return this; } @@ -988,7 +988,7 @@ public Options withExtraProjectFileExtensions( * * @return the project file extensions */ - public List getExtraProjectFileExtensions() { - return extraProjectFileExtensions; + public List getFrontendExtraFileExtensions() { + return frontendExtraFileExtensions; } } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 8bf2ff7a30a..6f45170ac74 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -29,7 +29,6 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.atmosphere.util.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,16 +131,12 @@ private void createGeneratedConfig() throws IOException { webComponentTags == null || webComponentTags.isEmpty() ? "" : String.join(";", webComponentTags)) - .replace("#extraProjectFileExtensions#", Optional - .ofNullable(options.getExtraProjectFileExtensions()) - .orElse(Collections.emptyList()).stream().map(ext -> { - try { - return "'" + StringEscapeUtils.escapeJava(ext) - + "'"; - } catch (Exception e) { - throw new RuntimeException(e); - } - }).collect(Collectors.joining(", "))); + .replace("#frontendExtraFileExtensions#", Optional + .ofNullable(options.getFrontendExtraFileExtensions()) + .orElse(Collections.emptyList()).stream() + .map(ext -> ext.replace("'", "\\'")) + .map(ext -> ext.startsWith(".") ? ext : "." + ext) + .collect(Collectors.joining("', '", ", '", "'"))); template = updateFileSystemRouterVitePlugin(template); FileIOUtils.writeIfChanged(generatedConfigFile, template); diff --git a/flow-server/src/main/resources/vite.generated.ts b/flow-server/src/main/resources/vite.generated.ts index 94390bc127f..7d323d8a9bc 100644 --- a/flow-server/src/main/resources/vite.generated.ts +++ b/flow-server/src/main/resources/vite.generated.ts @@ -298,7 +298,7 @@ function statsExtracterPlugin(): PluginOption { const frontendFiles: Record = {}; - const projectFileExtensions = ['.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map'#extraProjectFileExtensions#]; + const projectFileExtensions = ['.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map'#frontendExtraFileExtensions#]; const isThemeComponentsResource = (id: string) => id.startsWith(themeOptions.frontendGeneratedFolder.replace(/\\/g, '/')) diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java index 01810db521a..38ba59203f0 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -174,4 +175,27 @@ public void generatedTemplate_reactDisabled_correctFileRouterImport() template.contains(", vitePluginFileSystemRouter()")); } + + @Test + public void generatedTemplate_extraFrontendExtension_addedToViteConfiguration() + throws IOException { + options.withExtraFrontendFileExtensions( + Arrays.asList(".svg", ".ico", "png")); + TaskUpdateVite task = new TaskUpdateVite(options, null); + task.execute(); + + File configFile = new File(temporaryFolder.getRoot(), + FrontendUtils.VITE_GENERATED_CONFIG); + + String template = IOUtils.toString(configFile.toURI(), + StandardCharsets.UTF_8); + Pattern matchSelection = Pattern + .compile("const projectFileExtensions = \\[(.*)];"); + Matcher matcher = matchSelection.matcher(template); + Assert.assertTrue("No projectFileExtensions found", matcher.find()); + Assert.assertEquals( + "Extra frontend extensions should be added to vite configuration, but was not.", + "'.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map', '.svg', '.ico', '.png'", + matcher.group(1)); + } } diff --git a/flow-tests/test-frontend/vite-embedded-webcomponent-resync/pom.xml b/flow-tests/test-frontend/vite-embedded-webcomponent-resync/pom.xml index fbbb51ae3e4..dce8bfc80a9 100644 --- a/flow-tests/test-frontend/vite-embedded-webcomponent-resync/pom.xml +++ b/flow-tests/test-frontend/vite-embedded-webcomponent-resync/pom.xml @@ -99,6 +99,12 @@ + + + swg + ico + + From af99ce303d48086042fc6aac5d5245ac225709eb Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Wed, 6 Nov 2024 07:51:03 +0200 Subject: [PATCH 5/9] Add plugin data to runtime through build-info Fix initParam name, update javadocs --- .../gradle/VaadinFlowPluginExtension.kt | 2 +- .../plugin/maven/FlowModeAbstractMojo.java | 11 ++++----- .../flow/plugin/base/BuildFrontendUtil.java | 13 ++++++++-- .../vaadin/flow/server/InitParameters.java | 7 +++++- .../vaadin/flow/server/frontend/Options.java | 3 ++- .../flow/server/frontend/TaskUpdateVite.java | 24 ++++++++++++++----- .../startup/AbstractConfigurationFactory.java | 5 ++++ .../DeploymentConfigurationFactoryTest.java | 3 ++- .../server/frontend/TaskUpdateViteTest.java | 23 +++++++++++++++++- .../test-dev-bundle-frontend-add-on/pom.xml | 3 +++ .../src/main/frontend/styles/my-sass.scss | 3 +++ .../flow/frontend/DevBundleCssImportView.java | 3 +++ .../flow/frontend/DevBundleCssImportIT.java | 17 ++++++++++++- .../devserver/startup/DevModeInitializer.java | 21 ++++++++++------ 14 files changed, 111 insertions(+), 27 deletions(-) create mode 100644 flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/frontend/styles/my-sass.scss diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index 75e6420d242..1fbab3f05af 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -510,7 +510,7 @@ public class PluginEffectiveConfiguration( "alwaysExecutePrepareFrontend=${alwaysExecutePrepareFrontend.get()}, " + "frontendHotdeploy=${frontendHotdeploy.get()}," + "reactEnable=${reactEnable.get()}," + - "cleanFrontendFiles=${cleanFrontendFiles.get()}" + + "cleanFrontendFiles=${cleanFrontendFiles.get()}," + "frontendExtraFileExtensions=${frontendExtraFileExtensions.get()}" + ")" public companion object { diff --git a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java index b379805621f..8f806af91ec 100644 --- a/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java +++ b/flow-plugins/flow-maven-plugin/src/main/java/com/vaadin/flow/plugin/maven/FlowModeAbstractMojo.java @@ -238,14 +238,13 @@ public abstract class FlowModeAbstractMojo extends AbstractMojo /** * Parameter for adding file extensions to handle during frontend tasks. *

- * From the commandline use space separated list - * {@code -DfrontendExtraFileExtensions="svg ico"} + * From the commandline use comma separated list + * {@code -Ddevmode.frontendExtraFileExtensions="svg,ico"} *

- *

- * In plugin configuration + * In plugin configuration use comma separated values * - * svg - * ico + * + * svg,ico * * */ diff --git a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java index 94f0b6b3236..c82860907c3 100644 --- a/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java +++ b/flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/BuildFrontendUtil.java @@ -33,6 +33,7 @@ import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -74,6 +75,7 @@ import static com.vaadin.flow.server.Constants.NPM_TOKEN; import static com.vaadin.flow.server.Constants.PROJECT_FRONTEND_GENERATED_DIR_TOKEN; import static com.vaadin.flow.server.InitParameters.APPLICATION_IDENTIFIER; +import static com.vaadin.flow.server.InitParameters.FRONTEND_EXTRA_EXTENSIONS; import static com.vaadin.flow.server.InitParameters.FRONTEND_HOTDEPLOY; import static com.vaadin.flow.server.InitParameters.NODE_DOWNLOAD_ROOT; import static com.vaadin.flow.server.InitParameters.NODE_VERSION; @@ -166,7 +168,7 @@ public static void prepareFrontend(PluginAdapterBase adapter) .withHomeNodeExecRequired(adapter.requireHomeNodeExec()) .setJavaResourceFolder(adapter.javaResourceFolder()) .withProductionMode(false).withReact(adapter.isReactEnabled()) - .withExtraFrontendFileExtensions( + .withFrontendExtraFileExtensions( adapter.frontendExtraFileExtensions()); // Copy jar artifact contents in TaskCopyFrontendFiles @@ -266,6 +268,12 @@ public static File propagateBuildInfo(PluginAdapterBase adapter) { buildInfo.put(REACT_ENABLE, adapter.isReactEnabled()); + if (!adapter.frontendExtraFileExtensions().isEmpty()) { + buildInfo.put(FRONTEND_EXTRA_EXTENSIONS, + adapter.frontendExtraFileExtensions().stream() + .collect(Collectors.joining(","))); + } + try { FileUtils.forceMkdir(token.getParentFile()); FileIOUtils.writeIfChanged(token, @@ -408,7 +416,7 @@ public static void runDevBuildNodeUpdater(PluginAdapterBuild adapter) .skipDevBundleBuild(adapter.skipDevBundleBuild()) .withCompressBundle(adapter.compressBundle()) .withReact(adapter.isReactEnabled()) - .withExtraFrontendFileExtensions( + .withFrontendExtraFileExtensions( adapter.frontendExtraFileExtensions()); new NodeTasks(options).execute(); } catch (ExecutionFailedException exception) { @@ -743,6 +751,7 @@ public static void updateBuildFile(PluginAdapterBuild adapter, buildInfo.remove(NODE_DOWNLOAD_ROOT); buildInfo.remove(FRONTEND_TOKEN); buildInfo.remove(FRONTEND_HOTDEPLOY); + buildInfo.remove(FRONTEND_EXTRA_EXTENSIONS); buildInfo.remove(InitParameters.SERVLET_PARAMETER_ENABLE_PNPM); buildInfo.remove(InitParameters.SERVLET_PARAMETER_ENABLE_BUN); buildInfo.remove(InitParameters.CI_BUILD); diff --git a/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java b/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java index be19d6435c2..391291bb7a0 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/InitParameters.java @@ -179,6 +179,12 @@ public class InitParameters implements Serializable { */ public static final String APPLICATION_PARAMETER_DEVMODE_ENABLE_COMPONENT_TRACKER = "devmode.componentTracker.enabled"; + /** + * Configuration parameter name for adding extra file extensions for stats + * bundle to generate hashes for. + */ + public static final String FRONTEND_EXTRA_EXTENSIONS = "devmode.frontendExtraFileExtensions"; + /** * I18N provider property. */ @@ -285,5 +291,4 @@ public class InitParameters implements Serializable { */ public static final String APPLICATION_IDENTIFIER = "applicationIdentifier"; - public static final String FRONTEND_EXTRA_EXTENSIONS = "frontendExtraFileExtensions"; } diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java index c4b25be2761..8b55d72e62d 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/Options.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.net.URI; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Set; @@ -977,7 +978,7 @@ public boolean isCleanOldGeneratedFiles() { * the file extensions to add for the project * @return this builder */ - public Options withExtraFrontendFileExtensions( + public Options withFrontendExtraFileExtensions( List frontendExtraFileExtensions) { this.frontendExtraFileExtensions = frontendExtraFileExtensions; return this; diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 6f45170ac74..6703ca93681 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -23,6 +23,7 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -121,6 +122,8 @@ private void createGeneratedConfig() throws IOException { .getResource(FrontendUtils.VITE_GENERATED_CONFIG); String template = IOUtils.toString(resource, StandardCharsets.UTF_8); + System.out.println( + "=== '" + options.getFrontendExtraFileExtensions() + "'"); template = template .replace("#settingsImport#", "./" + options.getBuildDirectoryName() + "/" @@ -131,12 +134,8 @@ private void createGeneratedConfig() throws IOException { webComponentTags == null || webComponentTags.isEmpty() ? "" : String.join(";", webComponentTags)) - .replace("#frontendExtraFileExtensions#", Optional - .ofNullable(options.getFrontendExtraFileExtensions()) - .orElse(Collections.emptyList()).stream() - .map(ext -> ext.replace("'", "\\'")) - .map(ext -> ext.startsWith(".") ? ext : "." + ext) - .collect(Collectors.joining("', '", ", '", "'"))); + .replace("#frontendExtraFileExtensions#", + getFrontendExtraFileExtensions()); template = updateFileSystemRouterVitePlugin(template); FileIOUtils.writeIfChanged(generatedConfigFile, template); @@ -144,6 +143,19 @@ private void createGeneratedConfig() throws IOException { generatedConfigFile); } + private String getFrontendExtraFileExtensions() { + Optional> frontendExtraFileExtensions = Optional + .ofNullable(options.getFrontendExtraFileExtensions()); + if (frontendExtraFileExtensions.isPresent() + && frontendExtraFileExtensions.get().size() > 0) { + return frontendExtraFileExtensions.get().stream() + .map(ext -> ext.replace("'", "\\'")) + .map(ext -> ext.startsWith(".") ? ext : "." + ext) + .collect(Collectors.joining("', '", ", '", "'")); + } + return ""; + } + private String updateFileSystemRouterVitePlugin(String template) { if (options.isReactEnabled() && FrontendUtils.isHillaUsed( options.getFrontendDirectory(), options.getClassFinder())) { diff --git a/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java b/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java index 5063bbbc1d9..cced90c38f7 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java @@ -187,6 +187,11 @@ protected Map getConfigParametersUsingTokenData( String.valueOf(buildInfo.getBoolean(PREMIUM_FEATURES))); } + if (buildInfo.hasKey(InitParameters.FRONTEND_EXTRA_EXTENSIONS)) { + params.put(InitParameters.FRONTEND_EXTRA_EXTENSIONS, buildInfo + .getString(InitParameters.FRONTEND_EXTRA_EXTENSIONS)); + } + setDevModePropertiesUsingTokenData(params, buildInfo); return params; } diff --git a/flow-server/src/test/java/com/vaadin/flow/server/DeploymentConfigurationFactoryTest.java b/flow-server/src/test/java/com/vaadin/flow/server/DeploymentConfigurationFactoryTest.java index 62e1bdb1913..c9fd429591e 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/DeploymentConfigurationFactoryTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/DeploymentConfigurationFactoryTest.java @@ -350,7 +350,8 @@ public void createInitParameters_valuesAreTakenFromservletConfigAndTokenFile_val InitParameters.COMPILED_WEB_COMPONENTS_PATH, InitParameters.NODE_VERSION, InitParameters.NODE_DOWNLOAD_ROOT, InitParameters.BUILD_FOLDER, - InitParameters.APPLICATION_IDENTIFIER)); + InitParameters.APPLICATION_IDENTIFIER, + InitParameters.FRONTEND_EXTRA_EXTENSIONS)); Field[] initParamFields = InitParameters.class.getDeclaredFields(); String mockTokenJsonString = generateJsonStringFromFields( initParamFields, stringParams); diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java index 38ba59203f0..f78241aff8e 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/TaskUpdateViteTest.java @@ -179,7 +179,7 @@ public void generatedTemplate_reactDisabled_correctFileRouterImport() @Test public void generatedTemplate_extraFrontendExtension_addedToViteConfiguration() throws IOException { - options.withExtraFrontendFileExtensions( + options.withFrontendExtraFileExtensions( Arrays.asList(".svg", ".ico", "png")); TaskUpdateVite task = new TaskUpdateVite(options, null); task.execute(); @@ -198,4 +198,25 @@ public void generatedTemplate_extraFrontendExtension_addedToViteConfiguration() "'.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map', '.svg', '.ico', '.png'", matcher.group(1)); } + + @Test + public void generatedTemplate_noEraFrontendExtension_viteConfigurationWithoutExtraSelections() + throws IOException { + TaskUpdateVite task = new TaskUpdateVite(options, null); + task.execute(); + + File configFile = new File(temporaryFolder.getRoot(), + FrontendUtils.VITE_GENERATED_CONFIG); + + String template = IOUtils.toString(configFile.toURI(), + StandardCharsets.UTF_8); + Pattern matchSelection = Pattern + .compile("const projectFileExtensions = \\[(.*)];"); + Matcher matcher = matchSelection.matcher(template); + Assert.assertTrue("No projectFileExtensions found", matcher.find()); + Assert.assertEquals( + "Extra frontend extensions should be added to vite configuration, but was not.", + "'.js', '.js.map', '.ts', '.ts.map', '.tsx', '.tsx.map', '.css', '.css.map'", + matcher.group(1)); + } } diff --git a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/pom.xml b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/pom.xml index b5edddbdbed..4ef597ebb9d 100644 --- a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/pom.xml +++ b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/pom.xml @@ -111,6 +111,9 @@ + + scss + maven-clean-plugin diff --git a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/frontend/styles/my-sass.scss b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/frontend/styles/my-sass.scss new file mode 100644 index 00000000000..b07e52815e5 --- /dev/null +++ b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/frontend/styles/my-sass.scss @@ -0,0 +1,3 @@ +p { + border: 3px solid orange; +} diff --git a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/java/com/vaadin/flow/frontend/DevBundleCssImportView.java b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/java/com/vaadin/flow/frontend/DevBundleCssImportView.java index 8b26a4018ab..fe4a4c96812 100644 --- a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/java/com/vaadin/flow/frontend/DevBundleCssImportView.java +++ b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/main/java/com/vaadin/flow/frontend/DevBundleCssImportView.java @@ -16,12 +16,15 @@ package com.vaadin.flow.frontend; import com.vaadin.flow.component.dependency.CssImport; +import com.vaadin.flow.component.dependency.NpmPackage; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.Span; import com.vaadin.flow.router.Route; @Route("com.vaadin.flow.frontend.DevBundleCssImportView") @CssImport("./styles/my-styles.css") +@CssImport("./styles/my-sass.scss") +@NpmPackage(value = "sass-embedded", version = "1.80.6") public class DevBundleCssImportView extends Div { static final String MY_COMPONENT_ID = "test-css-import-meta-inf-resources-span"; diff --git a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/test/java/com/vaadin/flow/frontend/DevBundleCssImportIT.java b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/test/java/com/vaadin/flow/frontend/DevBundleCssImportIT.java index 831a6b9894d..769d0167791 100644 --- a/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/test/java/com/vaadin/flow/frontend/DevBundleCssImportIT.java +++ b/flow-tests/test-express-build/test-dev-bundle-frontend-add-on/src/test/java/com/vaadin/flow/frontend/DevBundleCssImportIT.java @@ -59,7 +59,22 @@ public void cssImportedStyles_hashCalculatedWithNotQuestionMark() found = true; } } - Assert.assertTrue("My-styles.css import is expected", found); + + Assert.assertTrue("my-sass.scss content hash is expected", + frontendHashes.hasKey("styles/my-sass.scss")); + Assert.assertEquals("Unexpected my-sass.scss content hash", + "719cbd39e90caeecd2290124044e7cefb9e6150d3c338d4df71c21bcad825ab5", + frontendHashes.getString("styles/my-sass.scss")); + + Assert.assertTrue("my-sass.scss import is expected", found); + found = false; + for (int i = 0; i < bundleImports.length(); i++) { + if (bundleImports.get(i).asString() + .equals("Frontend/styles/my-sass.scss")) { + found = true; + } + } + Assert.assertTrue("my-sass.scss import is expected", found); } @Test diff --git a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java index 67b2bc729b9..1241933368e 100644 --- a/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java +++ b/vaadin-dev-server/src/main/java/com/vaadin/base/devserver/startup/DevModeInitializer.java @@ -265,11 +265,11 @@ public static DevModeHandler initDevModeHandler(Set> classes, File frontendGeneratedFolder = new File(frontendGeneratedFolderName); File jarFrontendResourcesFolder = new File(frontendGeneratedFolder, FrontendUtils.JAR_RESOURCES_FOLDER); - JsonObject tokenFileData = Json.createObject(); Mode mode = config.getMode(); boolean reactEnable = config.getBooleanProperty(REACT_ENABLE, FrontendUtils .isReactRouterRequired(options.getFrontendDirectory())); + options.enablePackagesUpdate(true) .useByteCodeScanner(useByteCodeScanner) .withFrontendGeneratedFolder(frontendGeneratedFolder) @@ -279,7 +279,6 @@ public static DevModeHandler initDevModeHandler(Set> classes, Constants.LOCAL_FRONTEND_RESOURCES_PATH)) .enableImportsUpdate(true) .withRunNpmInstall(mode == Mode.DEVELOPMENT_FRONTEND_LIVERELOAD) - .populateTokenFileData(tokenFileData) .withEmbeddableWebComponents(true).withEnablePnpm(enablePnpm) .withEnableBun(enableBun).useGlobalPnpm(useGlobalPnpm) .withHomeNodeExecRequired(useHomeNodeExec) @@ -289,12 +288,13 @@ public static DevModeHandler initDevModeHandler(Set> classes, .withFrontendHotdeploy( mode == Mode.DEVELOPMENT_FRONTEND_LIVERELOAD) .withBundleBuild(mode == Mode.DEVELOPMENT_BUNDLE) - .withReact(reactEnable); + .withReact(reactEnable).withFrontendExtraFileExtensions( + getFrontendExtraFileExtensions(config)); + // Do not execute inside runnable thread as static mocking doesn't work. NodeTasks tasks = new NodeTasks(options); - Runnable runnable = () -> { - runNodeTasks(context, tokenFileData, tasks); + runNodeTasks(tasks); if (mode == Mode.DEVELOPMENT_FRONTEND_LIVERELOAD) { // For Vite, wait until a VaadinServlet is deployed so we know // which frontend servlet path to use @@ -329,6 +329,14 @@ public static DevModeHandler initDevModeHandler(Set> classes, } } + private static List getFrontendExtraFileExtensions( + ApplicationConfiguration config) { + List stringProperty = Arrays.asList(config + .getStringProperty(InitParameters.FRONTEND_EXTRA_EXTENSIONS, "") + .split(",")); + return stringProperty; + } + private static Logger log() { return LoggerFactory.getLogger(DevModeStartupListener.class); } @@ -350,8 +358,7 @@ static Set getFrontendLocationsFromClassloader( return frontendFiles; } - private static void runNodeTasks(VaadinContext vaadinContext, - JsonObject tokenFileData, NodeTasks tasks) { + private static void runNodeTasks(NodeTasks tasks) { try { tasks.execute(); } catch (ExecutionFailedException exception) { From dbab78f67e4ea2783303a9f388ebf0f14c78e28f Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Wed, 6 Nov 2024 09:18:05 +0200 Subject: [PATCH 6/9] remove debug comment --- .../java/com/vaadin/flow/server/frontend/TaskUpdateVite.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 6703ca93681..02ea343fa3a 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -122,8 +122,6 @@ private void createGeneratedConfig() throws IOException { .getResource(FrontendUtils.VITE_GENERATED_CONFIG); String template = IOUtils.toString(resource, StandardCharsets.UTF_8); - System.out.println( - "=== '" + options.getFrontendExtraFileExtensions() + "'"); template = template .replace("#settingsImport#", "./" + options.getBuildDirectoryName() + "/" From 2dee8a054a35619e4078741f8a34117c84f946ff Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Wed, 6 Nov 2024 09:21:09 +0200 Subject: [PATCH 7/9] trim extension to not have spaces fix gradle javadoc --- .../main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt | 2 +- .../java/com/vaadin/flow/server/frontend/TaskUpdateVite.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index 1fbab3f05af..9410e15416e 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -284,7 +284,7 @@ public abstract class VaadinFlowPluginExtension @Inject constructor(private val /** * The list of extra file extensions that are considered project files. - * Hashes are calculated for these files as part of detecting if a new prod + * Hashes are calculated for these files as part of detecting if a new * bundle should be generated. */ public abstract val frontendExtraFileExtensions: ListProperty diff --git a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java index 02ea343fa3a..2c3060adae5 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdateVite.java @@ -147,7 +147,7 @@ private String getFrontendExtraFileExtensions() { if (frontendExtraFileExtensions.isPresent() && frontendExtraFileExtensions.get().size() > 0) { return frontendExtraFileExtensions.get().stream() - .map(ext -> ext.replace("'", "\\'")) + .map(ext -> ext.replace("'", "\\'")).map(ext -> ext.trim()) .map(ext -> ext.startsWith(".") ? ext : "." + ext) .collect(Collectors.joining("', '", ", '", "'")); } From 671380c5914c17d7eaf453e85d318479a75827bf Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Thu, 7 Nov 2024 06:57:21 +0200 Subject: [PATCH 8/9] Add extra file extensions as input property --- .../kotlin/com/vaadin/gradle/PrepareFrontendInputProperties.kt | 3 +++ .../main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/PrepareFrontendInputProperties.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/PrepareFrontendInputProperties.kt index 79498ac60de..f710989e143 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/PrepareFrontendInputProperties.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/PrepareFrontendInputProperties.kt @@ -139,6 +139,9 @@ internal class PrepareFrontendInputProperties(private val config: PluginEffectiv @Input public fun getReactEnable(): Provider = config.reactEnable + @Input + public fun getFrontendExtraFileExtensions(): ListProperty = config.frontendExtraFileExtensions + @Input public fun getApplicationIdentifier(): Provider = config.applicationIdentifier diff --git a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt index 9410e15416e..9c918d93940 100644 --- a/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt +++ b/flow-plugins/flow-gradle-plugin/src/main/kotlin/com/vaadin/gradle/VaadinFlowPluginExtension.kt @@ -448,7 +448,7 @@ public class PluginEffectiveConfiguration( // TODO: Possibly get value from system param InitParameters.FRONTEND_EXTRA_EXTENSIONS public val frontendExtraFileExtensions: ListProperty = extension.frontendExtraFileExtensions - .convention(emptyList()) + .convention(listOf()) /** * Finds the value of a boolean property. It searches in gradle and system properties. From 00cb72b94ececb0f055e608c4c90f9615c212c6a Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Fri, 8 Nov 2024 07:09:56 +0200 Subject: [PATCH 9/9] format --- .../flow/server/startup/AbstractConfigurationFactory.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java b/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java index 8260025481a..ce9505e9f64 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/startup/AbstractConfigurationFactory.java @@ -189,9 +189,8 @@ protected Map getConfigParametersUsingTokenData( } if (buildInfo.hasKey(InitParameters.FRONTEND_EXTRA_EXTENSIONS)) { - params.put(InitParameters.FRONTEND_EXTRA_EXTENSIONS, - buildInfo.getString( - InitParameters.FRONTEND_EXTRA_EXTENSIONS)); + params.put(InitParameters.FRONTEND_EXTRA_EXTENSIONS, buildInfo + .getString(InitParameters.FRONTEND_EXTRA_EXTENSIONS)); } if (buildInfo.hasKey(NPM_EXCLUDE_WEB_COMPONENTS)) {