Production Mode doesn't work while everthing works well in development mode

First of all, does anybody knows what the difference are between “generated-flow-imports.js”, “generated-flow-imports-fallback.js”. The reason why I ask this question is that I found all the components in the “generated-flow-imports.js” works well but the one in “generated-flow-imports-fallback.js” doesn’t work.

I write an application with Vaadin 14.3.4 version, at the every begining , everything works well in development mode. After I want package them in the Production mode, I found some Polymer component written by myself doesn’t work. but some of them does.

The POM.xml file about the production mode shown as bellow:

<profile>
            <!-- Production mode is activated using -Pproduction -->
            <id>production</id>
            <properties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                    <version>2.3.4</version>
                </dependency>
                <dependency>
                    <groupId>com.codingapi.txlcn</groupId>
                    <artifactId>txlcn-tc</artifactId>
                    <optional>true</optional>
                </dependency>
                <dependency>
                    <groupId>com.codingapi.txlcn</groupId>
                    <artifactId>txlcn-txmsg-netty</artifactId>
                    <optional>true</optional>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <mainClass>com.basic.app.standalone.LumosBasicAppStandalone</mainClass>
                            <jvmArguments>-Dvaadin.productionMode</jvmArguments>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <version>14.3.4</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

after I run mvn -Pproduction clean package, I got one packaged jar file.

PS D:\code\vaadin14\lumos-appbase\lumos-appbase-app> mvn -Pproduction clean package
[INFO]
 Scanning for projects...
[INFO]

[INFO]
 --------------< com.ags.lumosframework:lumos-appbase-app >--------------
[INFO]
 Building lumos-appbase-app 5.0.0-SNAPSHOT
[INFO]
 --------------------------------[ jar ]
---------------------------------
[INFO]

[INFO]
 --- maven-clean-plugin:3.1.0:clean (default-clean) @ lumos-appbase-app ---
[INFO]
 Deleting D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target
[INFO]

[INFO]
 --- maven-resources-plugin:3.1.0:resources (default-resources) @ lumos-appbase-app ---
[INFO]
 Using 'UTF-8' encoding to copy filtered resources.
[INFO]
 Copying 2 resources
[INFO]
 Copying 0 resource
[INFO]

[INFO]
 --- maven-compiler-plugin:3.8.1:compile (default-compile) @ lumos-appbase-app ---
[INFO]
 Changes detected - recompiling the module!
[INFO]
 Compiling 2 source files to D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target\classes
[INFO]

[INFO]
 --- vaadin-maven-plugin:14.3.4:prepare-frontend (default) @ lumos-appbase-app ---
[INFO]
 Copying frontend resources from jar files ...
[INFO]
 Visited 335 resources. Took 2279 ms.
[INFO]

[INFO]
 --- vaadin-maven-plugin:14.3.4:build-frontend (default) @ lumos-appbase-app ---
[INFO]
 Scanning classes to find frontend configurations and dependencies...
[INFO]
 Visited 2309 classes. Took 3773 ms.
[INFO]
 Visited 131 classes. Took 94 ms.
[INFO]
 Skipping `npm install` because the frontend packages are already installed in the folder 'D:\code\vaadin14\lumos-appbase\lumos-appbase-app\node_modules' and the hash in the file 'D:\code\vaadin14\lumos-appbase\lumos-appbase-app\node_modules\.vaadin\vaadin.json' is the same as in 'package.json'
[INFO]
 Copying frontend resources from jar files ...
[INFO]
 Visited 335 resources. Took 1870 ms.
[INFO]
 Updated D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target\frontend\generated-flow-imports-fallback.js
[INFO]
 Updated D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target\frontend\generated-flow-imports.js
[INFO]
 Running webpack ...
         Emitted D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target\classes\META-INF\VAADIN/config/stats.json
Hash: 84e7bed7b0b061c8a9d7
Version: webpack 4.42.0
Time: 26677ms
Built at: 09/29/2020 3:00:52 PM
                                                                     Asset       Size  Chunks                                Chunk Names
                              build/vaadin-0-207c7ed32bfbbbd58763.cache.js    539 KiB       0  [emitted]
 [immutable]
    
                           build/vaadin-0-207c7ed32bfbbbd58763.cache.js.gz     92 KiB          [emitted]
                
                              build/vaadin-3-d99927ae15ccb618da01.cache.js   2.78 MiB       3  [emitted]
 [immutable]
  [big]

                           build/vaadin-3-d99927ae15ccb618da01.cache.js.gz    674 KiB          [emitted]
                
                              build/vaadin-4-8bd6bcf3f427431e06dc.cache.js   2.44 MiB       4  [emitted]
 [immutable]
  [big]

                           build/vaadin-4-8bd6bcf3f427431e06dc.cache.js.gz    641 KiB          [emitted]
                
                              build/vaadin-5-abb0bc7f5fbfc94ab516.cache.js   4.05 KiB       5  [emitted]
 [immutable]
    
                           build/vaadin-5-abb0bc7f5fbfc94ab516.cache.js.gz   1.48 KiB          [emitted]
                
                              build/vaadin-6-c20feb07e4aa72126f17.cache.js   4.05 KiB       6  [emitted]
 [immutable]
    
                           build/vaadin-6-c20feb07e4aa72126f17.cache.js.gz   1.48 KiB          [emitted]
                
                         build/vaadin-bundle-4a42a78c53fdf3915ef8.cache.js    951 KiB       1  [emitted]
 [immutable]
         bundle
                      build/vaadin-bundle-4a42a78c53fdf3915ef8.cache.js.gz    245 KiB          [emitted]
                
                     build/vaadin-bundle.es5-0aa20c3acb1dd6504a31.cache.js   1.11 MiB       2  [emitted]
 [immutable]
         bundle.es5
                  build/vaadin-bundle.es5-0aa20c3acb1dd6504a31.cache.js.gz    262 KiB          [emitted]
                
                                        build/webcomponentsjs/CHANGELOG.md   1.21 KiB          [emitted]
                
                                          build/webcomponentsjs/LICENSE.md   1.52 KiB          [emitted]
                
                                           build/webcomponentsjs/README.md   10.9 KiB          [emitted]
                
                         build/webcomponentsjs/bundles/webcomponents-ce.js     20 KiB          [emitted]
                
                     build/webcomponentsjs/bundles/webcomponents-ce.js.map    121 KiB          [emitted]
                
                   build/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js    116 KiB          [emitted]
                
               build/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js.map    675 KiB          [emitted]
                
                      build/webcomponentsjs/bundles/webcomponents-sd-ce.js   86.3 KiB          [emitted]
                
                  build/webcomponentsjs/bundles/webcomponents-sd-ce.js.map    546 KiB          [emitted]
                
                         build/webcomponentsjs/bundles/webcomponents-sd.js   67.2 KiB          [emitted]
                
                     build/webcomponentsjs/bundles/webcomponents-sd.js.map    426 KiB          [emitted]
                
                      build/webcomponentsjs/custom-elements-es5-adapter.js  954 bytes          [emitted]
                
                                        build/webcomponentsjs/package.json   2.74 KiB          [emitted]
                
build/webcomponentsjs/src/entrypoints/custom-elements-es5-adapter-index.js  659 bytes          [emitted]
                
       build/webcomponentsjs/src/entrypoints/webcomponents-bundle-index.js   1.66 KiB          [emitted]
                
           build/webcomponentsjs/src/entrypoints/webcomponents-ce-index.js  675 bytes          [emitted]
                
        build/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-index.js  860 bytes          [emitted]
                
     build/webcomponentsjs/src/entrypoints/webcomponents-sd-ce-pf-index.js   1.22 KiB          [emitted]
                
           build/webcomponentsjs/src/entrypoints/webcomponents-sd-index.js  767 bytes          [emitted]
                
                             build/webcomponentsjs/webcomponents-bundle.js    117 KiB          [emitted]
                
                         build/webcomponentsjs/webcomponents-bundle.js.map    678 KiB          [emitted]
                
                             build/webcomponentsjs/webcomponents-loader.js   6.13 KiB          [emitted]
                
Entrypoint bundle = build/vaadin-bundle-4a42a78c53fdf3915ef8.cache.js
Entrypoint bundle.es5 = build/vaadin-bundle.es5-0aa20c3acb1dd6504a31.cache.js
[117]
 ../node_modules/@vaadin/vaadin-text-field/theme/lumo/vaadin-text-field.js?babel-target=es6 + 1 modules 11 KiB {1} [built]

      |    2 modules
[118]
 ../node_modules/@vaadin/vaadin-text-field/theme/lumo/vaadin-text-field.js?babel-target=es5 + 1 modules 22.8 KiB {2} [built]

      |    2 modules
[244]
 ../node_modules/@vaadin/vaadin-dialog/theme/lumo/vaadin-dialog.js?babel-target=es6 + 1 modules 1.71 KiB {1} [built]

      |    2 modules
[245]
 ../node_modules/@vaadin/vaadin-text-field/theme/lumo/vaadin-password-field.js?babel-target=es6 + 1 modules 1.05 KiB {1} [built]

      |    2 modules
[246]
 ../node_modules/@vaadin/vaadin-dialog/theme/lumo/vaadin-dialog.js?babel-target=es5 + 1 modules 2.05 KiB {2} [built]

      |    2 modules
[247]
 ../node_modules/@vaadin/vaadin-text-field/theme/lumo/vaadin-password-field.js?babel-target=es5 + 1 modules 1.35 KiB {2} [built]

      |    2 modules
[274]
 ../node_modules/@vaadin/vaadin-custom-field/theme/lumo/vaadin-custom-field.js?babel-target=es6 + 1 modules 2.87 KiB {1} [built]

      |    2 modules
[275]
 ../node_modules/@vaadin/vaadin-form-layout/theme/lumo/vaadin-form-layout.js?babel-target=es6 + 1 modules 516 bytes {1} [built]

      |    2 modules
[276]
 ../node_modules/@vaadin/vaadin-grid/theme/lumo/vaadin-grid-sorter.js?babel-target=es6 + 1 modules 1.22 KiB {1} [built]

      |    2 modules
[277]
 ../node_modules/@vaadin/vaadin-grid/theme/lumo/vaadin-grid.js?babel-target=es6 + 1 modules 12.6 KiB {1} [built]

      |    2 modules
[278]
 ../node_modules/@vaadin/vaadin-custom-field/theme/lumo/vaadin-custom-field.js?babel-target=es5 + 1 modules 3.23 KiB {2} [built]

      |    2 modules
[279]
 ../node_modules/@vaadin/vaadin-form-layout/theme/lumo/vaadin-form-layout.js?babel-target=es5 + 1 modules 797 bytes {2} [built]

      |    2 modules
[280]
 ../node_modules/@vaadin/vaadin-grid/theme/lumo/vaadin-grid-sorter.js?babel-target=es5 + 1 modules 1.54 KiB {2} [built]

      |    2 modules
[306]
 ../target/frontend/generated-flow-imports.js?babel-target=es5 + 122 modules 774 KiB {2} [built]

      | ../target/frontend/generated-flow-imports.js?babel-target=es5 11.9 KiB [built]

      |     + 122 hidden modules
[307]
 ../target/frontend/generated-flow-imports.js?babel-target=es6 + 121 modules 650 KiB {1} [built]

      | ../target/frontend/generated-flow-imports.js?babel-target=es6 11.4 KiB [built]

      |     + 121 hidden modules
    + 795 hidden modules

WARNING in ../node_modules/@vaadin/flow-frontend/com/ags/lumosframework/web/vaadin/component/lumos-ck-editor.js?babel-target=es5 42:6-19
"export 'default' (imported as 'ClassicEditor') was not found in '@ckeditor/ckeditor5-build-classic'
 @ ../target/frontend/generated-flow-imports-fallback.js
 @ ../target/frontend/generated-flow-imports.js?babel-target=es5

WARNING in ../node_modules/@vaadin/flow-frontend/full-calendar.js?babel-target=es5 326:27-37
"export 'default' (imported as 'allLocales') was not found in '@fullcalendar/core/locales-all.min'
 @ ../target/frontend/generated-flow-imports-fallback.js
 @ ../target/frontend/generated-flow-imports.js?babel-target=es5

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (2 MiB).
This can impact web performance.
Assets:
  build/vaadin-3-d99927ae15ccb618da01.cache.js (2.78 MiB)
  build/vaadin-4-8bd6bcf3f427431e06dc.cache.js (2.44 MiB)
[INFO]
 update-frontend took 42659ms.
[INFO]

[INFO]
 --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ lumos-appbase-app ---
[INFO]
 Using 'UTF-8' encoding to copy filtered resources.
[INFO]
 skip non existing resourceDirectory D:\code\vaadin14\lumos-appbase\lumos-appbase-app\src\test\resources
[INFO]

[INFO]
 --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ lumos-appbase-app ---
[INFO]
 No sources to compile
[INFO]

[INFO]
 --- maven-surefire-plugin:2.22.2:test (default-test) @ lumos-appbase-app ---
[INFO]
 No tests to run.
[INFO]

[INFO]
 --- maven-jar-plugin:3.1.1:jar (default-jar) @ lumos-appbase-app ---
[INFO]
 Building jar: D:\code\vaadin14\lumos-appbase\lumos-appbase-app\target\lumos-appbase-app-5.0.0-SNAPSHOT.jar
[INFO]

[INFO]
 --- spring-boot-maven-plugin:2.2.5.RELEASE:repackage (repackage) @ lumos-appbase-app ---
[INFO]
 Replacing main artifact with repackaged archive
[INFO]
 ------------------------------------------------------------------------
[INFO]
 BUILD SUCCESS
[INFO]
 ------------------------------------------------------------------------
[INFO]
 Total time:  01:19 min
[INFO]
 Finished at: 2020-09-29T15:00:57+08:00
[INFO]
 ------------------------------------------------------------------------

after I run it, I found some page could not show but some could. Based my study, I found all the components listed in the “generated-flow-imports-fallback.js” doesn’t work.

generated-flow-imports.js is the main bundle that is always loaded. In production mode, the bundle size that the browser needs to download is optimized by only including JS modules that are reachable through the application’s entry points (e.g. classes with @Route). Analyzing bytecode to find out which classes might actually be reachable is a relatively slow operation that is skipped in development mode. Instead, it will contains everything from all @JsModule annotations on the classpath.

Anything that is on the classpath but isn’t determined to be reachable from the entry points is instead included in generated-flow-imports-fallback.js which can be loaded on demand. Whether to actually load the fallback bundle is determined by looking for annotations on component classes that are actually attached to the UI.

This basically means that there are two potential problems with your application:

  1. Components that are actually used are not detected as such which causes them to end up in the fallback bundle. This typically happens when the actual component implementations are not directly referenced but instead only injected based on an interface using e.g. Spring. You can force specific components to be included in the main bundle by referencing them in a @Uses annotation on a component class that is definitely detected as used, e.g. a @Route class.
  2. The logic that is supposed to load the fallback bundle is not triggered even though components that use those imports are actually attached to the UI. This might happen if those components are only used from a template and you have forgotten to actually import the components in the beginning of the template file. There’s also a possibility that there’s some problem with the server-side detection logic. To find out anything about that, I’d suggest putting a breakpoint in UIInternals.addFallbackDependencies to find out why it doesn’t reach any of the lines of code that does loadFallbackChunk().

Leif Åstrand:
generated-flow-imports.js is the main bundle that is always loaded. In production mode, the bundle size that the browser needs to download is optimized by only including JS modules that are reachable through the application’s entry points (e.g. classes with @Route). Analyzing bytecode to find out which classes might actually be reachable is a relatively slow operation that is skipped in development mode. Instead, it will contains everything from all @JsModule annotations on the classpath.

Anything that is on the classpath but isn’t determined to be reachable from the entry points is instead included in generated-flow-imports-fallback.js which can be loaded on demand. Whether to actually load the fallback bundle is determined by looking for annotations on component classes that are actually attached to the UI.

This basically means that there are two potential problems with your application:

  1. Components that are actually used are not detected as such which causes them to end up in the fallback bundle. This typically happens when the actual component implementations are not directly referenced but instead only injected based on an interface using e.g. Spring. You can force specific components to be included in the main bundle by referencing them in a @Uses annotation on a component class that is definitely detected as used, e.g. a @Route class.
  2. The logic that is supposed to load the fallback bundle is not triggered even though components that use those imports are actually attached to the UI. This might happen if those components are only used from a template and you have forgotten to actually import the components in the beginning of the template file. There’s also a possibility that there’s some problem with the server-side detection logic. To find out anything about that, I’d suggest putting a breakpoint in UIInternals.addFallbackDependencies to find out why it doesn’t reach any of the lines of code that does loadFallbackChunk().

Thank you very much!!!

After I debug my application, I found the follow things:

  1. The “FallbackChunk” in UI internal could not be fetched in the method “addFallbackDependencies”
  2. The reason why it could not be fetched is that VaadinServletService could not get the “DeploymentConfigurationFactory.FALLBACK_CHUNK” from the DeploymentConfiguration class.
  3. The Properties called “initParameters” contains the “DeploymentConfigurationFactory.FALLBACK_CHUNK” as the default value, but the method “get” will not fetch the value from the default one .so the following code in BOLD will never be reached:
 @Override
    public void init() throws ServiceException {
        DeploymentConfiguration deploymentConfiguration = getDeploymentConfiguration();
        Properties initParameters = deploymentConfiguration.getInitParameters();
        Object object = initParameters
                .get(DeploymentConfigurationFactory.FALLBACK_CHUNK);
**        if (object instanceof FallbackChunk) {
            VaadinContext context = getContext();
            context.setAttribute(object);
        }**
        super.init();
    }

So, This may be a bug.

18446324.png
18446327.png

Add more information
18446424.png

Thanks for investigating Yuri. This is indeed a bug in the handling of the fallback chunk in production mode with Spring Boot applications. Opened issue [spring/#662]
(https://github.com/vaadin/spring/issues/662) .