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

Importing from io-ts/es6 bundles (webpack) fp-ts/lib #349

Closed
wmaurer opened this issue Jul 2, 2019 · 10 comments
Closed

Importing from io-ts/es6 bundles (webpack) fp-ts/lib #349

wmaurer opened this issue Jul 2, 2019 · 10 comments

Comments

@wmaurer
Copy link

wmaurer commented Jul 2, 2019

🐛 Bug report

Current Behavior

If I import from io-ts/es6, fp-ts/lib ends up in the bundle (via webpack):
image

Expected behavior

Ideally I'd like fp-ts/es6 in the bundle. It would look like this:
image

(this result can be achieved with a work-around, see additional context section).

Reproducible example

If needed I can post a repo.

Additional context

There is a work-around, suggested by @jollytoad (to solve another issue):
gcanti/fp-ts#860 (comment)
I have also commented on the same issue, confirming that the work-around fixes the bundling problem:
gcanti/fp-ts#860 (comment)

Your environment

This problem effects io-ts versions 1 and 2.

Software Version(s)
io-ts 1 & 2
fp-ts 1 & 2
TypeScript 3.5.1
@gcanti
Copy link
Owner

gcanti commented Jul 3, 2019

@wmaurer what about replacing /lib/ with /es6/ everywhere in the es6 folder?

I mean

// file /lib/index.d.ts
import { Either } from 'fp-ts/lib/Either'; // <= lib is ok here
import { Predicate, Refinement } from 'fp-ts/lib/function';
// file /es6/index.d.ts
import { Either } from 'fp-ts/es6/Either'; // <= replace lib with es6
import { Predicate, Refinement } from 'fp-ts/es6/function';

would it fix this issue?

@wmaurer
Copy link
Author

wmaurer commented Jul 3, 2019

@gcanti thanks, I tested that out, and yes, it does fix the issue.

My feeling, though, is that even then there's room for improvement here - is there a way to avoid having to specifying either lib or es6 in code? When I import from rxjs I don't have to specify, and somehow the bundler chooses the correct one.
I believe it's rather complicated though. I wonder if there's a packaging utility that could help. In the Angular world, ng-packagr is the standard (bundles FESM2015, FESM5 and UMD), and it just works.

EDIT: when I look at the rxjs package.json there's a module field which points to es5, and an es2015 field which points to es2015. Combined with moving typings files around, I could imagine that it would be possible to achieve import * as O from 'fp-ts/Option', and webpack would pick up the correct version ...

@anilanar
Copy link

anilanar commented Jul 14, 2019

I'm also creating a library that has a dependency to fp-ts and the way I plan to resolve this is to use rollup.
Similar to io-ts's current setup, there will be two rollup configs, one for cjs and one for es6. The code will import fp-ts/lib/* and the es6 rollup config will alias fp-ts/lib to fp-ts/es6.
Once I do that in my library, I'll drop a PR here too, and possibly for other @gcanti libs that depend on fp-ts.

As @wmaurer mentioned, another solution (and a potentially better solution) would be to put every file into its own directory with all directories having its own package.json with main and module fields like:

/dist
|-- Functor
|   |-- index.cjs.js
|   |-- index.es6.js
|   |-- package.json
|-- Option
|   |-- index.cjs.js
|   |-- index.es6.js
|   |-- package.json
|-- ...
|-- ...
|-- index.cjs.js
|-- index.es6.js

This solution would have to generate a directory + package.json during build, not very hard but not trivial either.

@gcanti
Copy link
Owner

gcanti commented Dec 20, 2019

@wmaurer released a patch as io-ts@next (v2.0.3), could you please try it out?

@steida
Copy link

steida commented Jan 3, 2020

Correct me if I am wrong, but as I see it, with es6 tree shaking on the client-side via Webpack, is rollup for CommonJS necessary?

@steida
Copy link

steida commented Jan 3, 2020

@gcanti Have you seen recently released https://github.com/ReactiveX/rxjs/tree/master/src? It seems it's possible to have just one import path for everything.

@osdiab
Copy link
Contributor

osdiab commented Aug 20, 2020

I believe this can be closed now that #507 was merged and deployed? My bundle doesn't seem to include it.

@osdiab
Copy link
Contributor

osdiab commented Aug 20, 2020

That said, perhaps not related to this particular issue but I am interested in if there's potential for reducing the bundle size of this library - I use it only for io-ts and fp-ts alone is taking over 60kb before compression, which is not insignificant.

@gcanti
Copy link
Owner

gcanti commented Aug 20, 2020

@wmaurer @anilanar @steida from fp-ts@2.8.1 and io-ts@2.2.10 you should be able to import modules like this

import { Either } from 'fp-ts/Either'
import { PathReporter } from 'io-ts/PathReporter'

I use it only for io-ts and fp-ts alone is taking over 60kb before compression

@osdiab mmmh weird, the stable APIs should only use the Either module, could you please share a repro I can use in my tree shaking tests to see what's going on?

@osdiab
Copy link
Contributor

osdiab commented Aug 21, 2020

Ah it's probably because I use io-ts-types, io-ts itself should be fine!

@gcanti gcanti closed this as completed Aug 21, 2020
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

5 participants