Skip to content

Grid Helper Dense Mode does not work with productive build #171

Closed

Description

@timomeinen

Describe the bug

The dense mode does not work in production mode. Maybe the styles are not bundled when the production bundle is created?

Expected behavior

No response

Minimal reproducible example

No response

Add-on Version

2.0.0

Vaadin Version

25

Additional information

No response

Activity

  1. mlopezFC commented on Mar 19, 2026

    @mlopezFC
    Member

    Hi @timomeinen !
    Dense mode seems to be working on our demo application that is actually deployed in production mode.
    Can you try creating a new small sample application, integrate the add-on, copy the demos and then run it in production mode? .. if it works, compare it to your application to spot significant differences, if it doesn't attach the sample project here so we can take a look.
    Thanks!

  2. timomeinen commented on Mar 19, 2026

    @timomeinen
    Author

    Hi @mlopezFC,

    please find a small example of the problem here: https://github.com/timomeinen/grid-helpers-issue-171

    I have just added a checkbox of the DENSE mode to the start.vaadin.com demo application.

    I remember I had a similar issue with a different plugin and solved it by manually referencing the JS via Annotation to force it being packed into the prod.bundle. Here also the vaadin:build-frontend does not pickup the dependency and says, no bundle is needed:

    [INFO] --- vaadin:25.0.7:build-frontend (default-cli) @ app ---
    [INFO] Reflections took 725 ms to scan 118 urls, producing 5125 keys and 20651 values
    [INFO] Scanning classes to find frontend configurations and dependencies...
    [INFO] Visited 1255 classes. Took 1006 ms.
    [INFO] Checking if a production mode bundle build is needed
    [INFO] A production mode bundle build is not needed
    

    A production mode bundle build is not needed

  3. timomeinen commented on Mar 23, 2026

    @timomeinen
    Author

    The problem is that GridHelper is not recognized as Vaadin Component by the vaadin-maven-plugin and thus it does not recognize the @CssImport(value = "./fcGridHelper/vaadin-menu-bar.css", themeFor = "vaadin-menu-bar"). The result is that the CSS is missing in the bundle:

    ❯ grep "fcGridHelper/vaadin-menu-bar.css" target/classes/META-INF/VAADIN/config/stats.json

    In contrast the dev mode bundle has the required file:

    ❯ grep "fcGridHelper/vaadin-menu-bar.css" target/dev-bundle/config/stats.json
    
      "Frontend/generated/jar-resources/fcGridHelper/vaadin-menu-bar.css",
      "fcGridHelper/vaadin-menu-bar.css": "6d32eb58d19bd3dc5a606b217e67b7b358cca3d4eb55ed06b38c57e48fdeb9be",
    

    I tried to use com.vaadin.flow.component.dependency.Uses to give Vaadin a hint to include Grid-Helpers StyleSheets and JavaScript dependencies, but as GridHelper is not a com.vaadin.flow.component.Component it does not work:

    @Uses(GridHelper.class) // Compile error as GridHelper is not instanceof Component
    

    Instead, when we force bundling by disabling the byte-code scanner with <optimizeBundle>false</optimizeBundle>, it works:

    <plugin>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-maven-plugin</artifactId>
        <version>${vaadin.version}</version>
        <configuration>
            <optimizeBundle>false</optimizeBundle>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>build-frontend</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

    This will add the files to the prod bundle:

    ❯ grep "fcGridHelper/vaadin-menu-bar.css" target/classes/META-INF/VAADIN/config/stats.json
      "Frontend/generated/jar-resources/fcGridHelper/vaadin-menu-bar.css",
      "fcGridHelper/vaadin-menu-bar.css": "6d32eb58d19bd3dc5a606b217e67b7b358cca3d4eb55ed06b38c57e48fdeb9be",
    

    But this is not ideal as the prod bundle will now be unneccassary big.

  4. timomeinen commented on Mar 23, 2026

    @timomeinen
    Author

    Note: adding the CSS import to my own view, works as well of course:

    @CssImport(value = GridHelper.GRID_STYLES, themeFor = "vaadin-grid")

  5. javier-godoy commented on Mar 24, 2026

    @javier-godoy
    Contributor
  6. timomeinen commented on Mar 24, 2026

    @timomeinen
    Author

    Hi @javier-godoy,

    whitelisted-packages is deprecated but adding com.flowingcode is added to either whitelisted-packages or vaadin.allowed-packages:

    vaadin.whitelisted-packages=com.vaadin,org.vaadin,com.flowingcode,com.example.app
    vaadin.allowed-packages=com.vaadin,org.vaadin,com.flowingcode,com.example.app
    

    No change. the fcGridHelper resources are not added to the bundle:

    ❯ grep "fcGridHelper/" target/classes/META-INF/VAADIN/config/stats.json

  7. javier-godoy commented on Mar 24, 2026

    @javier-godoy
    Contributor

    I'll take a look.

  8. self-assigned this
    on Mar 24, 2026
  9. javier-godoy commented on Mar 26, 2026

    @javier-godoy
    Contributor

    The vaadin-maven-plugin production bundle scanner is reachability-based: it seeds from known entry points and follows bytecode references to discover @CssImport / @JsModule dependencies.

    When a view calls a GridHelper method, javac emits an instruction naming GridHelper as the owner class. The FrontendClassVisitor adds it to the reachability set, then the scanner visits GridHelper, and its @CssImport annotations are picked up. This is why our demo application works correctly in production (the demo for the dense theme feature is compiled with other demos that cause GridHelper to be reachable).

    In your sample project, only the DENSE_THEME constant is used. Javac inlines the constant and emits no field-access instruction at all
    (it's the same as if you had written grid.addThemeName("fcGh-dense")). Therefore GridHelper never appears in any executable instruction, the scanner never reaches it, and its annotations are not processed.

  10. added
    bugSomething isn't working
    and removed
    questionFurther information is requested
    on Mar 26, 2026
  11. added a commit that references this issue on Mar 26, 2026
    611a15a
  12. moved this from Inbox (needs triage) to In Progress in Flowing Code Addonson Mar 26, 2026
  13. added a commit that references this issue on Mar 27, 2026
    f44363c
  14. timomeinen commented on Mar 27, 2026

    @timomeinen
    Author

    The fix from commit 9ade7ea works, but I've created an alternative approach in #175 that I think is cleaner.

    Instead of the VaadinServiceInitListener anchor class, it adds setDenseTheme(Grid, boolean) and isDenseTheme(Grid) methods. This solves the production bundle problem the same way (a method call creates a bytecode reference to GridHelper, so the scanner finds its @CssImport annotations), but it's also more consistent with the rest of the GridHelper API where every feature follows the GridHelper.setSomething(grid, value) / GridHelper.isSomething(grid) pattern — the dense theme was the only one that required direct theme name manipulation.

  15. paodb commented on Mar 27, 2026

    @paodb
    Member

    Thanks @timomeinen for this alternative. It's really interesting, we will discuss about it next week and we will keep you posted.

  16. timomeinen commented on Apr 8, 2026

    @timomeinen
    Author

    Is it possible to release a patch version of the existing solution (GridHelperServiceInitListener) as we depend on this feature and I would like to get rid of my local hack?

  17. added a commit that references this issue on Apr 8, 2026
    4922c8b
  18. javier-godoy commented on Apr 8, 2026

    @javier-godoy
    Contributor

    @timomeinen I'll revert #173 and release it with your changes, since it's a more clear approach.

  19. added a commit that references this issue on Apr 8, 2026
    b5b552e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions