datavis-tech / graph-data-structure

A graph data structure with topological sort and shortest path algorithms.
MIT License
249 stars 46 forks source link

Support Tree Shaking / Selective Imports #18

Open curran opened 6 years ago

curran commented 6 years ago

As a developer, I want to be able to only include the functions required from this library, excluding the ones I don't need, so that I can minimize my bundle size.

Example scenarios:

yashmahalwal commented 4 years ago

As far as treeshaking is considered, I do have a simple way to go about it. I usually follow a specific directory structure. Consider this example,

Directory Structure for the package +-- _index.ts +-- MyModule | +-- index.ts

Now imagine that the MyModule -> index.ts file has a default export for that module of the package.

// MyModule -> index.ts
export default <ExportedValue>
// index.ts
export {default as MyModule} from './MyModule'

Now whenever I want to import ModuleName from the package, I can do

import {MyModule} from "package";

What difference does it make? Look at the above import. It currently imports the entire package to my codebase. But what if I wrote this?

import MyModule from "package/MyModule";

Now, only a single module from the package is imported. That is much better than a tree shaking plugin. You get minimalistic code bundle. Finally, there is a babel plugin that lets you do the following transform:

import {MyModule} from "package";

to

import MyModule from "package/MyModule";

This is a neat little trick I picked up from Material UI. If I use babel-plugin-transform-imports

import {Input} from '@material-ui/core'

Only adds -> @material-ui/core/Input to my codebase instead of adding the entire package.

Everything is properly organised and even if the user does not use the babel plugin, they get to choose exactly what they want due to the fine grained folder structure.

curran commented 4 years ago

Nice! It's definitely doable, just a matter of setting aside the time to refactor the codebase.

I do like the from "package/MyModule"; approach. Similar to how rxjs does it too, for example import { scan } from 'rxjs/operators';.

Thank you for this suggestion.

I'm also looking at this concept of an opaque data type to isolate the actual graph data structure from the algorithms. That way, the library can be a collection of functions that accept an instance of that data type, instead of being methods on the instance. Not 100% sure, but I think that's how I'd like to approach it.

yashmahalwal commented 4 years ago

Yeah that works. Opacity would also help seperate algorithms from implementation of the data structure which is always a nice thing to have around