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

Consider splitting across multiple packages / modules? #52

Open
dashed opened this issue Mar 27, 2014 · 15 comments
Open

Consider splitting across multiple packages / modules? #52

dashed opened this issue Mar 27, 2014 · 15 comments

Comments

@dashed
Copy link

dashed commented Mar 27, 2014

Any chance of splitting this library into multiple packages / modules?

I'd like to see something like http://lodash.com/custom-builds

@logankoester
Copy link

👍 this would be great!

@victorquinn
Copy link
Member

100% on board with this, just need time to break it up! I'll make it happen one of these days though, this would be fantastic. (unless someone wants to submit a PR for it sooner!)

Especially for plugins (because they could then be included in the build) and for some of the internationalization stuff where the list of American names is limiting/inappropriate.

@franciscop
Copy link

👍 for this. Some time ago I created a css library and the best thing I did was splitting it into plugins in the back end, it made maintenance much easier. I can try to help here, but I have a couple of questions:

  • Do you prefer to split it by section (Basics, Text, Person, etc) or by method (bool, character, floating)? Both would have advantages/disadvantages.
  • Is it an option to require a build step? This is the only sensible way of joining all of the modules together, and minimization could be included here. I guess the tool would be grunt for this since I see a Gruntfile.

@victorquinn
Copy link
Member

@franciscop I was hoping to have it split by section (Basics, Text, Person) and then also split by internationalization for those methods which required it (e.g. phone number, country identifiers like SSN, CPF, and the others which have been added).

I envisioned it using the defaults in each section then potentially having them overridden by internationalized versions in the build step.

So yes, a build step I thought necessary, probably with Grunt since that's what the library has already but I don't feel passionately about it, so if Gulp or something else would fit the bill that's fine.

Someone could build Chance with:

  • Everything
  • With only certain enumerated sections (e.g. ['web', 'mobile'] to build it with only web and mobile)
  • Optionally with internationalization (e.g. specifying no internationalization would build the default person identifier, SSN but including the international flag 'BR' would build a Brazilian version with the person identifier as the CPF instead and also generate a Brazilian postal code rather than the Americanized Zip).

We already have cli Chance support so I had hoped to obscure the complexity from the user allowing them to just run something like chance build with some option flags and get a custom version of chance.js spit out to the current directory with their requirements, very much like Lodash's cli.

This would make it super easy for folks to build it with the feature set they require. This would also allow us to add internationalized versions of things like first name and last name (so all the names aren't solely American) without making the library too large for client-side use.

@victorquinn
Copy link
Member

I should add part of the reason this hasn't been tackled yet is that it's not as easy as it may sound. There are a lot of co-dependencies which haven't been well mapped out.

For example the credit card exp_month() in what would be the Finance section depend on the month() generation in the Time section which depends on pick() method in the Helpers section which depends on natural() in the Basics section.

So untangling that knot and ensuring that things work is rather complicated without specifying the dependencies somehow.

@franciscop
Copy link

I see the problem. I have no idea of CLI actually, so I won't be able to do anything related to it, but I can try to separate it in different parts. There's one caveat though, I don't know how to do it when using the global closure that you are using:

function(){
  // code
}();

What I have done in the past is instead having a unique global variable and making everything its descendent. I think a similar structure might be possible for Chance (or a better one if I find how to keep the global closure). See the demo:

// chance.js
var Chance = function(seed) {
    // ...
}

// basics.js
Chance.prototype.bool = function(){
    console.log("AAA");
}

Chance.prototype.whatever = function(){
    this.bool();
}

// end.js
chance = new Chance();

The problem is that you will need a separate part only to do chance = new Chance(). Another option is stop using the prototypes.

Prototypes help when an object is going to be created many times as they reduce the cost of declaring everything. Since, from the documentation and examples I see, only one instance of chance is normally used then we do not incur on this cost if we do it like this demo:

// chance.js
var chance = function(seed) {
    // ...
}

// basics.js
chance.bool = function(){
    console.log("AAA");
}

chance.whatever = function(){
    this.bool();
}

In both cases the constants and other scoped variables would be added to chance. What do you think? Is this an option?

@franciscop
Copy link

I will have time and motivation to do this in January. I've just finished organizing the source code for Umbrella JS into plugins:

src/
  plugins/
    addclass/
      addclass.js
      test.js
    adjacent/
      adjacent.js
    ...
  umbrella.js
  test.js

Then Umbrella's Gruntfile.js gets the file umbrella.js and concatenates each of the plugins at the end when running grunt. In this way you can still use each of the plugins inside others with no dependency problem as you can see.

Is this structure and methodology feasible for Chance.js?

@mesqueeb
Copy link

Just wanted to see if there is any update for webpack deconstruction. : )
eg:

import { integer } from 'chance'

to only get the integer functionality, to prevent bloating.

Great library btw!

@TheLarkInn
Copy link

TheLarkInn commented Jun 23, 2018

Hey @victorquinn I'm Sean, from webpack! 👋

I have a branch that I've been playing around with for a week or so, that has broken all methods out into their own raw ES Modules. Of course this would force users to have to have some sort of build step, and I got rid of the seeding so that unused methods didn't have to be packed up together and can be used without loading a lot of JSON data over the wire (even if unused).

https://github.com/chancejs/chancejs/compare/master...TheLarkInn:feature/rewrite-to-modules?expand=1

What do you think about this? I've gotten it to the point where all but a few tests (seed, instantiation based stuff which I got rid of) are passing.

@leomeloxp
Copy link

@TheLarkInn or @victorquinn do you happen to have any updates on this? I'd be very interested in benefiting from being able to import only a subset of Chance's features (and I currently use webpack on by build process so that wouldn't be an issue).

I think ideally we would have ways of pulling the current chance package from CDNs (and maybe NPM somehow) but would have an opt-in way of importing chance's features as modules for those with a build pipeline that supports such features (or are shipping ES Modules once that is better supported on browsers).

Thanks in advance.

@rockerest
Copy link

Another bump on this: I don't really care about importing subsetted modules (treeshaking will take care of that for me, in most cases), but I do - very much - care about using this in ES6-module environments. Having to load a CJS bundler just for Chance bums me out :)

I'm hoping that a side effect of using modules will mean that I can directly import Chance or import *. It looks like @TheLarkInn's fork may provide this (I'm looking at a test that does import * as chance).

@GrayStrider
Copy link

Bump, looking for a way to get treeshaking work properly

@mesqueeb
Copy link

mesqueeb commented Mar 3, 2020

It sounds to me like @TheLarkInn from webpack has done all the work already, someone with edit rights should come in, merge changes, and deploy to npm.

@victorquinn in 2014 you said you needed to give this issue some time, how's it looking now in 2020? 😉

@GrayStrider
Copy link

chance.pickone(['do the thing', '17KB who cares', 42])

@victorquinn
Copy link
Member

Sorry all for the delays. I have it on the 2.0 branch where I’ve split into a mono repo using Lerna. You can see it here #438

The way it’s set up it actually allows me to push small components to npm for each generator. See https://www.npmjs.com/package/@chancejs/bool for an example

It’s just a big undertaking but I’d gladly accept any and all help to keep making progress on it!

But this is the way forward, just needs to be executed

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

No branches or pull requests

9 participants