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

Webpack bundle for Node.js? #105

Closed
ai opened this issue Aug 18, 2017 · 25 comments
Closed

Webpack bundle for Node.js? #105

ai opened this issue Aug 18, 2017 · 25 comments

Comments

@ai
Copy link

ai commented Aug 18, 2017

For next steps of reducing size I need the decision from you.

j8nhbdb

Right now EmojiMart bundle everything including dependencies to webpack bundle at dist/emoji-mart.js and dist/emoji-mart.min.js. As result we have 3 problems:

  1. The user will have 2 webpack preambles (webpack inner functions and magic) — one from their webpack, second from EmojiMart.
  2. Even if the user has own core-js they anyway will have 2 core-js copies — one from their dependencies, second from EmojiMart. The main problem that core-js is really big. About 10% of the current EmojiMart bundle.
  3. PropTypes slow down JS execution in production and keep size in the EmojiMart bundle. If the user has own PropTypes, they will have 2 copies of PropTypes.

My plan of size optimization:

  1. During build process compile files by Babel to dist/, but don’t bundle them into the single file. package.json’s main will target to dist/index.js. Anyway, most of React users have webpack or other bundlers.
  2. Bundle this files to dist/emoji-mart.min.js for backward compatibility, but do not use this file in package.json’s main.
  3. core-js and all other dependencies will be in package.json dependencies and required with require('core-js'). So we will use same core-js as the user already has.
  4. Remove PropTypes with babel-plugin-transform-react-remove-prop-types.
  5. Try to find code uses process and rewrite it, so webpack will not insert process polyfill.

Question for @EtienneLem:

  1. Do we really need dist/emoji-mart.min.js? I understand this file for jQuery plugins, etc. But it is extremely rare to use React without any bundler.
  2. Do we really need core-js? Maybe we can rewrite code, that uses some ES6 classes? Or just put the warning to docs, if you need to support IE 11, please add core-js (for example, we do not send huge core-js to everyone, we send it only to IE 11 users).
@ai
Copy link
Author

ai commented Aug 18, 2017

On step 2 will optimize data/index.js. In caniuse-lite we found many ways to keep JSON size smaller.

@ai
Copy link
Author

ai commented Aug 21, 2017

@EtienneLem if questions are complicated, just tell me your concern. I will find extra data for decision.

@EtienneLem
Copy link
Member

Sorry for the delay and thanks for doing that research! 🤘


  1. Do we really need dist/emoji-mart.min.js? I understand this file for jQuery plugins, etc. But it is extremely rare to use React without any bundler.

You’re right, it’s very unlikely. 👍 for removing it.

  1. Do we really need core-js? Maybe we can rewrite code, that uses some ES6 classes? Or just put the warning to docs, if you need to support IE 11, please add core-js (for example, we do not send huge core-js to everyone, we send it only to IE 11 users).

Looking at yarn.lock lots of dependencies seem to be using core-js, so I’m not too sure I fully understand how that would work (or why/how/since when we use it ourselves 😅). Anyway, I’m not against forcing developers into having to include it themselves instead of having it bundled if it’s related to IE11 support.

@ai
Copy link
Author

ai commented Aug 22, 2017

Fine. What do you think about this plan:

  1. dist/emoji-mart.*.js will be removed. We will just compile files src/* to dist/* with Babel (without webpack). main will be dist/index.js. We will have files like dist/components/emoji.js, etc. User will be able to load only special components by require('emoji-mart/dist/components/emoji') (but it is rare case).
  2. core-js will be in dependencies. Let’s not broke IE 11 :D.

So breaking changes:

  1. Non-bundler users will need to run own webpack to bundle EmojiMart to one files (not sure that we have this users).
  2. require('emoji-mart/dist/emoji-mart.min') will not work anymore. Not sure that somebody did it before.

As result we will have same API and some supported browsers.

If users don’t need core-js they could remove it by webpack plugins (i will remove it in my project :-P).

If everythin is OK, I will start making PR after my talk in China. PR will be at beginning of September.

@EtienneLem
Copy link
Member

Sounds good to me 👍

@danfernand
Copy link

How much do you think this will lower the size of the dependency? this dependency is at the top of the list in size.

$ webpack --config webpack/prod.config.js --json | webpack-bundle-size-analyzer
emoji-mart: 899.54 KB (21.7%)

@ai
Copy link
Author

ai commented Aug 22, 2017

@danfernand my plan is to reduce 50%. But in the first step I afraid I will be able to reduce only 10-20%.

@danfernand
Copy link

so im thinking of forking since I only need a subset of all the categories, i was able to get the total bundle by omitting categories that i don't care for in build data. Could making this an env variable help out to reduce bundle size. Nobody likes symbols!

@danfernand
Copy link

screen shot 2017-08-22 at 5 10 49 pm

@EtienneLem
Copy link
Member

That’s a good idea, it’d be nice if we could find a way to make it easy for developers to build data from their bundler (webpack, browserify, etc) instead of postinstall.

@danfernand
Copy link

Also, instead of calculating the data file and adding to the bundle we could push to a cdn, might be better in the long run to do that since that calculation doesn't change very much.

It would reduce the bundle by more then half plus other changes you are proposing will really make this a lightweight dependency.

I can help with the data file in the sky problem if you think that is a good idea.

@EtienneLem
Copy link
Member

Maybe if data could be split from the library (#86) then it can be up to the developers to provide data the way they want, but until then I don’t think it’d be an advantage over bundling it. data needed to do a complete emoji picker is — unfortunately — huge, but even on a CDN people using the picker would still need to download it. I’d prefer not to add network into the mix, being able to use the lib offline surely is a must for most.

If we do make it so data generation is customizable when bundling, we’d be just a few steps away from #86. Would then be pretty trivial for developers to download a data file from a CDN 😄

@n-filatov
Copy link

Hi. I replaced webpack tasks on babel for dist build in #108

@ai
Copy link
Author

ai commented Sep 3, 2017

@EtienneLem I asked @Muffassa to help us with this issue by my plan.

@ai
Copy link
Author

ai commented Sep 3, 2017

@EtienneLem PR from @Muffassa was finished. When you will accept it, I will try to remove process polyfill and then it will be ready for release.

@davojta
Copy link

davojta commented Sep 10, 2017

Seems right now date/index.js is not processed by babel and broke node env (jest tests for example as jest dont compile to commonjs whole node_module tree). But that behaviour could be fixed by changing data/index.js generation to commonjs module format and marking measure-scrollbar in jest like

... "transformIgnorePatterns": [ "<rootDir>/node_modules/(?!measure-scrollbar)" ] ...

@davojta
Copy link

davojta commented Sep 10, 2017

Also seems that in dist without webpack generation EMOJI_DATASOURCE_VERSION is absent. It is provided by webpack define plugin on build time.

@ai
Copy link
Author

ai commented Sep 11, 2017

@davojta thanks for this issue. I fixed them and few others in #110.

But I didn’t understand your suggestion about measure-scrollbar. Tests work good and I didn’t find any issues.

@EtienneLem also, this time I made an integration test :). I copied dev version to node_modules/emoji-mart and check that everything works on my website (at least in Chrome).

@davojta
Copy link

davojta commented Sep 11, 2017

@ai It's not suggestion, it's issue on my project and linked how babel-jest process dependencies for node_modules ( just for deep level 1 it babelifyes the modules - other required modules ( with level 2 and more in dependency graph) is not processed.

I can provide repo example for the issue.

Thank you to pay attention to my feedback!

@ai
Copy link
Author

ai commented Sep 11, 2017

@davojta can you check EmojiMart from my PR? Maybe I fixed problem :D

@davojta
Copy link

davojta commented Sep 11, 2017

@ai yes it will fix the problem with default backgroundImageFn and with data/index.js

But if webpack will be used to process SVG we will have error - i've used ReactSVG to eliminate the problem - davojta@8fa705f

@shaypeleg1
Copy link

shaypeleg1 commented Oct 15, 2017

The bundle size is still 618kb after build, what am I missing here?
v 2.1.1

@ai
Copy link
Author

ai commented Oct 15, 2017

After Uglify and gzip?

@shaypeleg1
Copy link

after using react-scripts (create-react-app) to build minified js I don't know about Uglify and gzip, should I configure something else?

@ai
Copy link
Author

ai commented Oct 15, 2017

You got different number. Size Limit shows size after UglifyJS and gzip.

Just ignore difference, everything is fine.

But reading about UglifyJS and gzip is always good.

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

6 participants