Open xdenser opened 3 years ago
How do I reproduce this? Where should I put the line of code with the dynamic import?
in js/ts file in frontend folder.
And a hint how to fix this:
see webpack documentation
https://webpack.js.org/api/stats/
BootstrapHandler looks only in field "assetsByChunkName"
but there is also "initial":boolean field in "chunks" array.
If this is true then chunk should be loaded during boostrap, otherwise this is dynamic chunk and webpack should load it in runtime. Well I am not sure about this last part - how webpack will detect proper url - this needs further investigation.
But as first try I would just filter out chunks that have initial == false
, and rely on webpack for dynamic loading.
Is BootstrapHandler still supported in Vaadin19? It should be if it is public class in jar.
Yes, but since Vaadin 15+ the modules are injected in a different way, writing the initial chunk import to the index.html page and that chunk loads all the other chunks - there are several since even the client engine is now processed by webpack.
When I add the initial
flag to our stats plugin, only one chunk, with id-0, gets the "initial": "true"
property in json. HtmlWebpackPlugin
injects a script
loading this chunk to the index.html. But I see that in addition to that, the chunk-0 loads the chunks 1-3 too even though those have "initial": "false"
. But I'm quite sure that those would have to be loaded anyway after first chunk. And maybe this is doing what you are describing - loading non-initial dynamic chunks when needed? I have not found the place which decides what other chunks are loaded by the chunk-0, but at least it is not loading everything as there are actually more chunks.
For Flow 2.x (Vaadin 14 series), I think there are only two chunks - "the optimized everything that is used chunk" and the "fallback chunk". I can edit the code to make it so that the initial
property is output to stats.json and then it is considered when adding the chunks to the bootstrap page, but I'm not sure if it really makes a difference or will everything be still to the same chunk - unless we add support to 14-series for splitting the bundle further. I doubt that it would be a priority - but I can help you get forward in trying that if you want to @xdenser
OK I will try to create reduced example. I just want to load big library only when needed. In my case this is ace editor - which otherwise would add 500Kb for initial load and is only used in some rare scenarios in our application. But just for example we, of course, do not need ace editor. Some alert() in dynamically imported module will be enough.
To have impression how it looks like:
my code is inspired by this addon
https://vaadin.com/directory/component/ace/overview
but this one does not fit our needs and actually created for Vaadin 14
But ace is loaded similar way like here :
https://github.com/F0rce/lit-ace/blob/c6e8d5de7b72d72bcfca2491e4d7e899f4f8d788/lit-ace.js#L152
but in our case without this base path thing( we refer to 'ace-builds' as normal npm module) - and by this trick imho author of the addon tries to workaround this bug of initial loading - probably webpack just ignores this import - i did not try to use this addon in our code.
But again it is better to create reduced example. I have more difficulties how to simulate our bootstrap there. The example itself is rather simple.
Ok here is example. run, Open About view and press the button. And actually dynamic module loading works correctly unless webpack chunk name directive is used. See frontend/dynamicModuleLoader.ts line 11 my-app.zip w/o directive the js file is loaded when you press button, with directive it is loaded (but not executed) at boostrap.
How to reproduce:
just use
var dynamicImport = await import('dynamic-module');
in the code. And see that 'dynamic-module' is loaded immediatelly with boostrap page. Did not test it with Vaadin15+ way of boostraping. Is BootstrapHandler still supported in Vaadin19? It should be if it is public class in jar.