frintjs / frint

Modular JavaScript framework for building scalable and reactive applications
https://frint.js.org/
MIT License
755 stars 34 forks source link

Move lodash to peerDependencies to avoid multiple imports to bundle file. #419

Closed EduardTrutsyk closed 6 years ago

EduardTrutsyk commented 6 years ago

I analyzed bundle file with webpack-bundle-analyzer and notice that each frint package includes lodash. To avoid this, my suggestion is move lodash to peerDependencies to avoid multiple imports to bundle file.

screenshot at 17-40-32

fahad19 commented 6 years ago

Before we go into making any decision, I would like to explain how dependencies and peerDependencies are used with FrintJS packages at the moment.

dependencies

Lodash and RxJS are direct dependencies of most frint-* packages. They are used internally, and end-users are not expected to be aware of them.

For example, in frint package:

https://github.com/frintjs/frint/blob/master/packages/frint/src/App.ts#L2-L5

Since end-users are not expected to know about them, lodash gets installed under the hood when we install frint:

$ npm install --save frint

peerDependencies

React itself, on the the other hand, is treated as a peer dependency by frint-react-* packages. This is because the end-user is expected to know and use React themselves with their preferred React version.

This has allowed us to keep FrintJS compatible with React 0.14,15.x, and16.x` at most times simultaneously, making migration in our custom applications an easy and predictable process.

When we want to use frint-react, we also ask end-users to install React at the same time:

$ npm install --save react prop-types frint-react

Note about bundle size

Not all of lodash or rxjs are imported by frint-* packages. Since v5 release, they are imported individually, like this:

import { isFunction } from 'lodash/isFunction'; // more specific module path
import { map } from 'rxjs/operators/map';

This has significantly helped reduce overall bundle size of custom applications using FrintJS.

About external analyzer tools

If any external analyzer tool is suggesting that we import lodash in multiple frint-* packages, then they are right. We do use lodash across multiple packages.

But we also need to understand that custom applications are supposed to include most of their third-party libraries into a single common bundle/chunk, like vendors.js.

When a common chunk appears into the scene, lodash modules would only be loaded once via that chunk (not more than once). Meaning, the browser will never have duplicate entries for lodash modules.

Automated analysis from tools like webpack-bundle-analyzer can be misleading then :)

fahad19 commented 6 years ago

will close this issue later today unless there is any further feedback.

EduardTrutsyk commented 6 years ago

Hi @fahad19 webpack-bundle-analyzer works perfect, when I try to install npm packages via npm and yarn, I have two different results. as you can see, yarn resolve packages correctly, but we are using npm: screenshot at 15-17-48 screenshot at 15-15-27

Screenshot from production vendors.js: screenshot at 13-18-56

EduardTrutsyk commented 6 years ago

Hi @fahad19, the problem was with incorrect version of lodash, I think we can close this issue.