direflow icon indicating copy to clipboard operation
direflow copied to clipboard

Make build tree-shakeable

Open johnmcase opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe. Currently the build produced by direflow does not allow the consumer to fully tree-shake out only the files that are being used. Specifically this is a problem with any 3rd party libraries that the Direflow components depend on.

If the build is created with split=true and vendor=false then each component file contains all of it's own dependencies. This is good, except for the case where multiple components share the same dependency. In that case the dependency is duplicated in each of those components.

If the build is created with split=true and vendor=true then ALL of the dependencies are placed in the vendor.js file. Therefore any consuming application that wants to use a subset of components in the build must load ALL of the 3rd party libraries, regardless of whether or not they actually need them all.

Consider the following example:

Direflow is used to produce a library of many web components, Some of the components <heavy-one> and <heavy-two> have dependencies on a 3rd party library, we'll call it heavy.js. Another component, <lite-component>, has a dependency on lite.js. This library is then published out to an NPM repository (public or private) so that these components may be consumed by web applications. Lets call this package my-direflow-library.

A web application then imports my-direflow-library but it is small and only uses a subset of the components.

Scenario with vendor bundle is good? without vendor bundle is good?
<heavy-one> and <lite-component> used heavy.js and lite.js are included in app bundle yes heavy.js and lite.js are included in app bundle yes
Only <heavy-one> used heavy.js and lite.js are included in app bundle NO Only heavy.js is included in app bundle yes
Only <lite-component> used heavy.js and lite.js are included in app bundle NO Only lite.js is included in app bundle yes
<heavy-one> and <heavy-two> used heavy.js and lite.js are included in app bundle NO 'heavy.js' is included in app bundle TWICE NO

Describe the solution you'd like Ideally the Direflow build process would be smart enough to split the vendor.js bundle into multiple files such that consuming applications only need to load the minimal amount of dependencies. I believe this would be easier to achieve if Direflow output proper ES6 modules.

Describe alternatives you've considered None

Additional context Add any other context or screenshots about the feature request here.

johnmcase avatar Sep 12 '20 00:09 johnmcase

Hi @johnmcase Thank you for creating a very thorough and well-formulated issue.

Yes, the scenarios above are all true. We iterated over the goal of making the output bundles smaller, multiple times. The biggest measure we have taken thus far is to asynchronically load the biggest dependencies, React modules and the Web Component polyfills, thus making sure that the bundle is not render-blocking while doing so.

The next step would definitely be to make the bundles tree-shakeable to a better extend, but it is not as easy as it may sound. Outputting ES6 modules is the logical next step, however - it does introduce other problems.

I'm gonna keep this issue open and include it in our project board. It's very clear and well-written, and it is something that we will have to look into, down the road.

Thanks a lot for taking the time :pray:

SimonHoiberg avatar Sep 15 '20 03:09 SimonHoiberg