vaadin / vaadin-gradle-plugin

Gradle plugin for Vaadin 14 applications. Takes care of front-end build, helps to configure repositories and to create various project and file templates.
Apache License 2.0
31 stars 9 forks source link

stats.json not packaged to WAR #107

Closed mvysny closed 3 years ago

mvysny commented 3 years ago

Currently the stats.json is generated into the build/vaadin-generated/META-INF/VAADIN/config/ folder, along with flow-build-info.json. However, stats.json is generated after Gradle copies stuff from build/vaadin-generated to build/resources/main, therefore stats.json file is not packaged. Vaadin is able to run without stats.json both in dev and in production mode, however certain things will not work (for example PolymerTemplate and LitTemplate).

Desktop (please complete the following information):

To Reproduce TBD once the Gradle plugin 0.20.0.0.alpha3 is released.

Expected behavior The stats.json is generated to build/resources/main which will then cause Gradle to package it correctly to WAR.

Additional context The incorrect path can be seen in webpack.generated.js:

const mavenOutputFolderForResourceFiles = path.resolve(__dirname, 'build/vaadin-generated/META-INF/VAADIN');
...
const confFolder = path.resolve(mavenOutputFolderForResourceFiles, 'config');
const serviceWorkerPath = 'sw.js';
// file which is used by flow to read templates for server `@Id` binding
const statsFile = `${confFolder}/stats.json`;

Currently the flow-build-info.json is generated in build/vaadin-generated/META-INF/VAADIN/config/ (that is good); however is there a way to force stats.json to be generated elsewhere (in build/resources/main/META-INF/VAADIN/config/stats.json)?

caalador commented 3 years ago

The reason that we can start the project without the stat.json is probably becaus Fusion adds the bundle into the index.html <script defer="defer" src="VAADIN/build/vaadin-bundle-433c776b2a8a219d4f73.cache.js"> which I guess is loaded when not using useDeprecatedV14Bootstrapping as then I guess we might use the IndexHtmlRequestHandler instead of the BootsrapHandler.

mvysny commented 3 years ago

There is also a deeper issue here: the WAR file will package an older version of flow-build-info.json. I think it goes like this:

caalador commented 3 years ago

So should the files just be directly created to build/resources/main instead of creating it to build/vaadin-generated?

mvysny commented 3 years ago

Maybe.... I'm trying to remember the reason why we're using build/vaadin-generated instead of creating stuff simply in build/resources/main...

A fix could either be to generate stuff directly to build/resources/main, or alternatively I wonder what would happen if we configure Gradle to run processResources AFTER vaadinBuildFrontend like this:

project.tasks.getByName("processResources").mustRunAfter("vaadinBuildFrontend")

Let me investigate on this further.

There's some info on this here: https://github.com/vaadin/vaadin-gradle-plugin/pull/44

mvysny commented 3 years ago

Uh-oh, using project.tasks.getByName("processResources").mustRunAfter("vaadinBuildFrontend") fails right away with

:classes
\--- :processResources
     \--- :vaadinBuildFrontend
          \--- :classes (*)

The vaadinBuildFrontend task needs to depend on classes, to be able to analyze e.g. @CssImport annotations used by the project.

But maybe it could be enough to only depend on compileJava according to https://docs.gradle.org/current/userguide/java_plugin.html? Not good - what about compileKotlin and possibly other tasks hooked to classes?

mvysny commented 3 years ago

Generating token file to build/resources/main before processResources doesn't work: the processResources will delete the build/resources/main folder. Maybe run vaadinPrepareFrontend after processResources?

mvysny commented 3 years ago

That works! However, running Intellij+Tomcat will invoke Gradle to build the war file, which in turn will invoke processResources, thus removing the flow-build-info.json file produced by vaadinPrepareFrontend? Investigate.

mvysny commented 3 years ago

Just as I suspected: Intellij+Tomcat ignores stuff present in build/resources/main, making Vaadin fail that it can't locate pom.xml in tomcat/bin folder. A separate source folder is therefore needed.

The only way forward is to make vaadinPrepareFrontend to generate the token file to build/vaadin-generated as before, but then make vaadinBuildFrontend work in the scope of build/resources/main.