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

Script size #452

Open
claytongulick opened this issue Sep 10, 2019 · 15 comments
Open

Script size #452

claytongulick opened this issue Sep 10, 2019 · 15 comments
Labels
v4 Issues that require a major version bump to resolve

Comments

@claytongulick
Copy link

General information

  • SDK version: 3.x
  • Environment: both
  • Browser and OS all

Issue description

The generated dist/index.js is pretty big and drastically increases the size of release bundles. This is especially painful when the only thing being used is client and hostedFields, which is a pretty common scenario. let {client, hostedFields} = require('braintree-web') is over 500k!

package.json has a browser field that redirects webpack includes to the dist folder, which also has built versions of client and hostedFields that are much larger than they need to be due to polyfills etc...

In many builds these are redundant and prevent effective tree-shaking, or reuse of existing polyfill libs.

The workaround for this is to require('braintree-web/client/index.js') directly, this prevents the 'browser' redirect in package.json from taking effect. By doing this, it's possible to reduce the size of the included script massively. Webpack analyzer shows my size decreased to 50k, gzipped 14.5k. There's probably room to decrease this even more, since a lot of the deps appear to be coming from /lib, which looks like some materialized versions of some libs that (may?) be npm installable.

While many users will need to link directly to a /dist script, the 'browser' field should probably be removed from package.json. That's only going to be used by folks who already have a build solution, like webpack or browserify, and for those users it's better to just allow webpack to follow the requires and do it's thing.

@crookedneighbor
Copy link
Contributor

We added the browser field to accommodate some problems with using Webpack with Angular 6 with our data collector package: #366

We could look into including a browser field only for data collector, and let the rest of the modules use the source files instead. We'll discuss it as a team and get back to you.

The next major version we release will utilize tree shaking, so it should be easier to idiomatically import the module.

@crookedneighbor crookedneighbor added the v4 Issues that require a major version bump to resolve label Sep 11, 2019
@claytongulick
Copy link
Author

Since v4 is going to fix it, for now maybe just some docs that call out the issue and the workaround?

@719media
Copy link

719media commented Oct 25, 2019

@claytongulick you can try to do

import braintreeClient from 'braintree-web/client';
import braintreeHostedFields from 'braintree-web/hosted-fields';

to get what you want

@nstuyvesant
Copy link

Oddly, when I use the approach

import client from 'braintree-web/client';
import hostedFields from 'braintree-web/hosted-fields';
import applePay from 'braintree-web/apple-pay';

I get errors:

Could not find a declaration file for module 'braintree-web/hosted-fields'. '/Users/foo/dev/shy3/node_modules/braintree-web/hosted-fields/index.js' implicitly has an 'any' type. Try npm install @types/braintree-web if it exists or add a new declaration (.d.ts) file containing `declare module 'braintree-web/hosted-fields'

I already had @types/braintree-web installed.

@crookedneighbor
Copy link
Contributor

That types file was not created or maintained by Braintree.

We're planning on writing the next major version of the JS SDK in typescript, so it'll have all the type definitions automatically.

Until then, you'll have to provide your own declaration files for the module.

@nstuyvesant
Copy link

Ah, I see. So the problem is the 3rd party types don't separate the types by module such as 'braintree-web/client' and 'braintree-web/hosted-fields'.

How far in the future is the next major version of the JS SDK?

@crookedneighbor
Copy link
Contributor

Don't have a timeline on it yet, but we're working on it.

@potty
Copy link

potty commented Dec 20, 2020

Hi, glad to hear you are working on a Typescript rewrite. Is there any ETA for it? Current types are pretty bad, have to use a lot of @ts-ingore as the types support mostly deprecated API only.

@crookedneighbor
Copy link
Contributor

There's no ETA yet, but you can see that we've already completed the Typescript script conversion for the underlying modules that the SDK depends on (framebus, card-validator, event-emitter, etc)

I can say that we're starting to focus on the rewrite over adding new features to the current version. When we're ready to get people to start testing some beta releases of the new version, we'll comment on each of the issues marked with a v4 label.

@KasperAndersson
Copy link

Hi @crookedneighbor ,
When is v4 planned? The bundle size still seems to be a issue.

@crookedneighbor
Copy link
Contributor

I don't have an ETA on a release for the next version. I can say we're actively working on it.

For now, within npm, the main package entry point should never be used, as it contains references to every single component. You should always use this strategy to get just the components you need: #452 (comment)

@macrozone
Copy link

we also noticed this problem, the bundle size of braintree is enormous. That's weird in times of tree-shaking.

#452 (comment) could be a solution, but having no types declaration is not ideal.

@kirillgroshkov
Copy link

I've heard that Stripe SDK is in TypeScript and tree-shakeable ;)

@daelmaak
Copy link

daelmaak commented Aug 9, 2023

Oddly, when I use the approach

import client from 'braintree-web/client';
import hostedFields from 'braintree-web/hosted-fields';
import applePay from 'braintree-web/apple-pay';

I get errors:

Could not find a declaration file for module 'braintree-web/hosted-fields'. '/Users/foo/dev/shy3/node_modules/braintree-web/hosted-fields/index.js' implicitly has an 'any' type. Try npm install @types/braintree-web if it exists or add a new declaration (.d.ts) file containing `declare module 'braintree-web/hosted-fields'

I already had @types/braintree-web installed.

I have a PR open that will solve this issue in the declaration files.

@daelmaak
Copy link

It's merged, if you use TypeScript, you can now import braintree like this

import client from 'braintree-web/client';
import hostedFields from 'braintree-web/hosted-fields';
import applePay from 'braintree-web/apple-pay';

and spare some bundle size until v4 is out 🤞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v4 Issues that require a major version bump to resolve
Projects
None yet
Development

No branches or pull requests

9 participants