Open mifi opened 1 year ago
This could also help in cases like this https://github.com/transloadit/uppy/issues/4218#issuecomment-1399409372 even though those plugins might be combined, I think the option to dynamically load, enable/disable would be a fantastic addition
Problem
From discussion here: https://github.com/transloadit/uppy/pull/4225#issuecomment-1321834598
Bundle size is large if developers want to support all upload methods or plugins, even those that are not actually used by the user - simply importing our plugins gives a large bundle size.
Solution
It would be nice to start out with a minimal uploader (small bundle size) that can be inlined (like the Mini proposal). Then once users select other upload sources in the UI, we could dynamically load chunks for those plugins using JS dynamic imports.
For example from #4225 when the user click "Dropbox" in the menu, then chunks for the dashboard and Dropbox plugin would be loaded and shown. This would allow for a minimal core to be loaded much faster with the site.
I did some testing where I started a Create-react-app project (uses webpack) and then added two fake dependencies inside
node_modules
:uppy-plugin-audio
uppy-plugin-webcam
Then another
uppy
folder insidenode_modules
that will dynamically import these two dependencies.Test setup
First run:
Create these files:
Now build the bundles and start a static server:
Results
Check network tab in DevTools
It has loaded
/static/js/main.adcf708b.js
- 151kBNow click "Audio" button - it will load the audio chunk
/static/js/78.c46b4426.chunk.js
- 220kbNow click "Webcam" button - it will load the webcam chunk
/static/js/38.f157b14b.chunk.js
- 220kbAnalyze webpack bundle:
Conclusion
From my testing, dynamic imports from inside npm modules works with a popular framework like create-react-app (webpack). Because dynamic imports are now part of the web, it leads me to believe that most bundlers support this now. This POC shows that we should be able to modify Uppy so that instead of the developer using Uppy having to manually handle importing Uppy dependencies/plugins and passing them to
uppy.use
, Uppy can instead internally dynamically import plugins once the functionality that uses them is being opened.Downsides:
Alternatives
Alternative 1
The developer using Uppy can use dynamic import when importing Uppy. Then their bundle will be small and we don't have to change anything, but once Uppy needs to be imported, they will still have to load all the plugins. (big bundle)
Alternative 2
We could pass the responsibility of dynamically importing plugins onto the developer using Uppy. Then we would modify Uppy so that instead of importing plugins when the user calls
uppy.use(plugin)
, we could use an option that Uppy can call when Uppy needs a particular plugin (kind of like dependency injection, but async). something like: