vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
602 stars 165 forks source link

Rethink "production builds" and get rid of production profile #17737

Open mstahv opened 11 months ago

mstahv commented 11 months ago

Describe your motivation

Currently our project build files looks ugly and you need special Vaadin skills to build a deployable artifact (typically in Maven project build with production profile that builds the front-end bundle). This makes deploying Vaadin applications harder than it should be and requires special tricks when for example using packeto buildpacks to pack your Vaadin app.

In addition to "just" not being like a standard Java project, this makes Vaadin build files look much more complicated.

Describe the solution you'd like

Make our Maven plugin smarter so that we don't need a special profile for it. It could detect if the front-end build is needed from the environment and/or have some flag to trigger developmentmode/productionmode.

With cloud native buildpacks I have for example used this configuration in my pom.xml to enable production front-end build:

        <activation>
            <property>
                <name>env.CNB_TARGET_OS</name>
                <value>linux</value>
            </property>
        </activation>

But there are probably other ways to detect the situation as well. And most likely we need a flag to set this explicitly as well.

knoobie commented 11 months ago

For Jenkins I do:

   <activation>
        <!-- Profile that is automatically activated when run in Jenkins because Jenkins creates a env.BUILD_NUMBER-->
        <property>
          <name>env.BUILD_NUMBER</name>
        </property>
    </activation>
Legioth commented 11 months ago

Could we do production builds by default? If you do mvn or mvn spring-boot:run, then you want to run in development mode. If you do mvn package or mvn install, then you want to build for production. The same is also the case with Quarkus or if you use e.g. wildfly-maven-plugin or jetty-maven-plugin.

It's a special case if you want to build a .war or .jar that isn't for production use. Maybe we should have a dedicated profile (or just documentation) for that case instead?

knoobie commented 11 months ago

I'm not sure how good the automatic detection works with all the possible configuration options for the flow maven plugin and e.g. looking at my configuration how different it is for development and production mode. I also often run mvn clean install locally in multi module projects where Vaadin is only used in one and I don't care about a runnable artefact for that anyway, cause I'm starting it locally with spring boot anyway and just need to refresh IDEAs cache or testing other things.

Legioth commented 11 months ago

Good point. You might do mvn install locally because you've got a multi-module project even though you're not actually interested in a slow production build for for the Vaadin part.

On the other hand, we might also have a simpler default for tutorials and starters that are based on the single-module use case where production could be the default and then separately show a multi-module setup where a production build isn't the default?

knoobie commented 11 months ago

It depends on the audience Vaadin wants to target with this. I don't have the numbers, but I would think that multi module projects are wider used in corporate environments, so this change would only benefit starters in terms of repo and developer / user.

I personally would more focus on the idea of Matti and improve auto detection of environments where the production build normally runs (GitHub, gitlab, Jenkins, bit bucket and so on) and activate the profile by default

mstahv commented 11 months ago

The most common case for development mode is you launch it via IDE's public static void main string args support. If we can detect that (or everything else) and provide a flag to set development mode explicitly πŸ€”

knoobie commented 11 months ago

Now I'm feeling like a unicorn, never done that, always using the mvn boot run command 🀫

mcollovati commented 11 months ago

Now I'm feeling like a unicorn, never done that, always using the mvn boot run command

You're not alone, we are at least in two :grin:

Legioth commented 11 months ago

One thing to keep in mind here is that we're always balancing between two partially conflicting goals:

  1. Keep the getting-started experience as easy as possible for new users. We want to make sure they immediately get on a path towards succeeding with Vaadin. This means that we want to have good defaults and we want to make things like the default pom.xml file look simple rather than intimidating.
  2. Help users succeed with all the complex stuff that pops up in real-world applications. It's acceptable if users need to do som additional setup based on their needs as long as we can guide them in the right direction.
knoobie commented 11 months ago

Don't get me wrong, I totally understand the desire and need to appeal to new developer - especially those that are scared away by more than two lines of config (over exaggerated). But I feel that the amount of "goodies" are already plenty out there with the default development and prod bundle making the whole development process for new developer or rapid prototyping relatively painless.

Just some ideas:

All those points expect that people are able to read cough - let's hope, with ChatGPT and others.. people are more likely to read than before..

mstahv commented 6 months ago

Here is a design for you. Prototyped this a bit with V24.4 test project and at least for Spring Boot based projects I'm quite confiden this would work pretty well:

I suggest to do the dev-mod scope change "today", for Vaadin 24.4, and others ASAP without a rush (at least with a bit of creativity I believe it to be possible to introduce these in a perfectly backwards compatible manner whenever we want, only build plugin changes required).

mstahv commented 6 months ago

After some further investigation, the above is not a perfect solution as such for Spring Boot apps until https://github.com/spring-projects/spring-boot/issues/25403 gets fixed. Based on how Spring Boot treats spring-boot-devtools I kind of thought optional dependencies are not packed in by Spring Boot, but they are, and SB plugin just excludes devtools. Thus, the production jar works in production mode with the prototype, but contains obsolete stuff we don't want there (without further configuration of spring-boot-maven plugin).

With standard war projects (or Quarkus probably) this would nail it.

shymega commented 5 months ago

I'm just curious about this sentence from OP's post:

requires special tricks when for example using Packeto buildpacks to pack your Vaadin app.

I'm trying to deploy a Hilla app on Fly.io, with Spring Native and Paketo Buildpacks. However, I can't get past the build-frontend exception due to Vite not being located.

I'm assuming OP was referring to that. I would be very grateful if the workaround for this was put in the original issue, or as a comment - just as a workaround. I've subscribed to this issue in the meantime.

knoobie commented 5 months ago

Please create a issue in Hilla; it should work if configured correctly and used. This issue is about resucing the need for special config altogether.

shymega commented 5 months ago

Please create a issue in Hilla; it should work if configured correctly and used. This issue is about resucing the need for special config altogether.

Apologies, I felt this is also a Flow issue as the problematic Maven plugin inherits from Flow.

Feel free to hide my original comment as off-topic, and I'll do some more digging to figure out where the best place for the issue would be. At this point, I'm fairly certain it's a Flow Maven issue.

I'm still curious about the workaround OP used (if they did?), but I appreciate this isn't the place to discuss that.

mstahv commented 4 months ago

Sorry I missed the continued discussion here and returning to the subject bit late (I have overflow in GH notifications 😬). Did you try the trick/workkaround I use (mentioned in the issue description) to active the production profile by default? I think that should work for you.

mstahv commented 2 months ago

I have been iterating a PoC towards my understanding of "the ideal state", back and forth, with different approaches, for way too long without releasing anything for public discussion. Just a while ago I finally pushed our now a first public iteration for comments. Maven central is probably still syncing, but quite soon you ought to be able to test the example project from this repository https://github.com/viritin/viritin-sb

Things to notice and test, the important parts:

With these things in core Vaadin would feel much easier to take into use for experienced Java developer (partly perceived feeling, but very important!) and would provide less head-ache when integrating to various systems in the cloud era.

Notes about implementation details of this poc in its current form:

Heading now to test this in a couple of hobby projects, please help my by doing the same!

mstahv commented 2 months ago

Update, version 0.0.2 of the PoC published in previous comment also works with Hilla (smoke tested).

mstahv commented 1 month ago

Updates regarding my PoC:

Dudeplayz commented 3 weeks ago
  • Starting the app from IDE (main method) ( or in the @knoobie method πŸ˜‰ using mvn spring-boot:run), gets you into development mode (no special Vaadin knowledge needed if you want back to the dev mode after mvn package)

Please keep quarkus:dev in mind, as it is clear for what purpose it is used. Quarkus also allows remote development, which could be a use case were an build is intended with development bundle. I am not using this actually, but it came in my mind.

mstahv commented 3 weeks ago

Good point @Dudeplayz. I'm quite confident that this approach can be applied in some for Quarkus apps as well at least with some plugin code. As dev mode is in quarkus started with the CLI tooling or maven plugin, it might even be easier to intercept dev mode startups. Maybe @mcollovati has some good ideas how to get a similar exprience with QuarkusπŸ€”