Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom import generator #40

Open
axefrog opened this issue Mar 26, 2017 · 2 comments
Open

Custom import generator #40

axefrog opened this issue Mar 26, 2017 · 2 comments

Comments

@axefrog
Copy link
Member

axefrog commented Mar 26, 2017

Functional imports when using multiple collections is fiddly and messy because you end up with loads of imports to manage in every source file, and you have to use aliasing a lot to account for commonalities among function names (e.g. freeze, get, etc.). I've discovered that a good pattern is to create an internal collections script that imports all of the required functions and exports them as unified collection types/namespaces. It's better for this to be done by the consuming application, because you lose the ability to tree-shake unused imports, so you want to make sure you only expose the methods you're actually using.

In the docs area, I want a page that lets you select all the collections and methods you want, then automatically generates a script with all of imports and exports ready to go.

Example script that would be generated:

export {batch, isMutable, isImmutable} from '@collectable/core';

import {
  List as _List,
  fromArray as list_fromArray,
  size as list_size,
  get as list_get,
  iterate as list_iterate,
  skip as list_skip,
  take as list_take,
} from '@collectable/list';

export type List<T> = _List<T>;
export namespace List {
  export const fromArray = list_fromArray;
  export const size = list_size;
  export const get = list_get;
  export const iterate = list_iterate;
  export const skip = list_skip;
  export const take = list_take;
}

import {
  Map as _Map,
  empty as map_empty,
  entries as map_entries,
  keys as map_keys,
  get as map_get,
  set as map_set,
  thaw as map_thaw,
  isFrozen as map_isFrozen,
  update as map_update,
} from '@collectable/map';

export type Map<K, V> = _Map<K, V>;
export namespace Map {
  export const empty = map_empty;
  export const entries = map_entries;
  export const keys = map_keys;
  export const get = map_get;
  export const set = map_set;
  export const thaw = map_thaw;
  export const isFrozen = map_isFrozen;
  export const update = map_update;
}

import {
  SortedMap as _SortedMap,
  SortedMapEntry,
  empty as smap_empty,
  get as smap_get,
  set as smap_set,
  thaw as smap_thaw,
  isFrozen as smap_isFrozen,
  update as smap_update,
} from '@collectable/sorted-map';

export type SortedMap<K, V> = _SortedMap<K, V>;
export namespace SortedMap {
  export const empty = smap_empty;
  export const get = smap_get;
  export const set = smap_set;
  export const thaw = smap_thaw;
  export const isFrozen = smap_isFrozen;
  export const update = smap_update;

  export function KeyComparator(a: SortedMapEntry<any, any, any>, b: SortedMapEntry<any, any, any>): number {
    return a.key - b.key;
  }
}

import {
  Set as _Set,
  empty as set_empty,
  add as set_add,
  remove as set_remove,
  values as set_values,
  isEmpty as set_isEmpty,
} from '@collectable/set';

export type Set<T> = _Set<T>;
export namespace Set {
  export const empty = set_empty;
  export const add = set_add;
  export const remove = set_remove;
  export const values = set_values;
  export const isEmpty = set_isEmpty;
}

import {
  SortedSet as _SortedSet,
  empty as sset_empty,
  add as sset_add,
  remove as sset_remove,
} from '@collectable/sorted-set';

export type SortedSet<T> = _SortedSet<T>;
export namespace SortedSet {
  export const empty = sset_empty;
  export const add = sset_add;
  export const remove = sset_remove;
}
@TylorS
Copy link
Contributor

TylorS commented Mar 26, 2017

Couldn't you also just do

import * as List from '@collectable/list'
import * as Map from '@collectable/map'

export { List, Map } 

I'm pretty sure that rollup and webpack2 would still tree-shaking that (?)

@axefrog
Copy link
Member Author

axefrog commented Mar 26, 2017

Yeah definitely, it's more about this:

import {get as mapGet, set as mapSet, ......................................} from '@collectable/map';
import {get as listGet, set as listSet, ......................................} from '@collectable/list';
// and way more imports here

vs

import {Map, List} from './collections';

let list: List<string>, Map<number, string>;
// ...
list = List.empty<string>();
let list2 = List.append('a', list);
map = Map.fromArray([[0, 'a']]);
let map2 = Map.set(0, 'b', map);

The latter is much easier to manage, it doesn't suffer from having to constantly organise your imports as your code evolves to use or not use a given named import, and you still get tree-shaking, because even though you've bundled a bunch of functions into a singular export, you still have control over what your application uses, without dragging in extraneous stuff that will bloat your bundle with redundant code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants