Yomguithereal / talisman

Straightforward fuzzy matching, information retrieval and NLP building blocks for JavaScript.
https://yomguithereal.github.io/talisman/
MIT License
709 stars 47 forks source link

Add a module field in package.json #100

Open DavidBruant opened 7 years ago

DavidBruant commented 7 years ago

For rollup support https://github.com/rollup/rollup/wiki/pkg.module

Yomguithereal commented 7 years ago

Hello @DavidBruant. Should this module point to the actual sources of the library in ES2015? Is that it?

DavidBruant commented 7 years ago

I think so. The idea is that with this field ES2015-module-capable bundlers (like rollup) can look at the ES2015 sources and after static analysis can choose to not bundle all modules/functions, but only the parts that are actually imported. See example in rollup website

Yomguithereal commented 7 years ago

There is a slight issue however: this library does not have just a single endpoint but rather multiple ones. You cannot really do var talisman = require('talisman'); or else. Rather, you are meant to import each of the needed features one by one not to bloat builds etc.

DavidBruant commented 7 years ago

not to bloat builds

In the past-present, library authors carry the burden of separating their code so that consumers do not have too bloated builds when using only a small number of features. In the ES6-module future, bundlers can perform static analysis to understand what is actually used and pick the parts that are actually needed (implicitly relieving library authors from the burden as long as they use the syntax and separate their functions properly).

Please take a look at the example in http://rollupjs.org/ to see it in action.

The module field is the way we do the bridge between "past-present" and "ES6-module future"

Yomguithereal commented 7 years ago

I know that static analysis & tree-shaking etc. make the splitted modules irrelevant in the future but there is still an issue here concerning the fact that you really don't want to have a single endpoint for this library. First because this means else that in node, you will load all the code (except if you do some transpiling server-side, which is awkward) just to access some tiny part of it. And second because it would mean perform strange things such as:

import talisman from 'talisman';

// Let's get the Levenshtein distance
const distance = talisman.metrics.distance.levenshtein;

// Or if we flatten the namespaces, but this will make it hard to organize the code
const distance = talisman.levenshtein;

I admit that this library has an issue concerning namespacing because I need it to be in only one package for the moment because I am iterating on the concepts of the library while learning to use & code them. Which means that in an hypothetical future it would probably be better indeed to split the main namespaces in child libraries such as talisman-tokenizers and so on, but I can't do it right now because things evolves too fast.

DavidBruant commented 7 years ago

you really don't want to have a single endpoint for this library. First because this means else that in node, you will load all the code

Adding an entrypoint file does not mean people have to use it. It just means that it exists. It does not remove the ability to import specific modules independently as they do today.

You can choose to remove the main field but have a module field anyway which content could be something along the line of what d3 does (except directories instead of dependencies in your case).

I think (but never tried) that if you do NOT name your module field file index.js and remove the main field, it will remain impossible to import writing require('talisman'). Best of all worlds.