Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Feature Request: Clarify package contents & allow for better tree shaking #127

Closed
ericgio opened this issue Apr 5, 2018 · 13 comments
Closed

Comments

@ericgio
Copy link

ericgio commented Apr 5, 2018

Hi guys, thanks for the great libraries (both react-popper and popper.js).

I ran into this issue today and couldn't figure out at first why it was happening until I realized that the package contents weren't quite what I expected. I was able to solve the issue, but am no longer able (as far as I can tell) to easily tree shake the components I'm not using.

My request/suggestion is twofold:

  1. Change the package folder structure to make it more clear what the contents are. The most common approach I've seen is to provide a dist folder containing the minified and unminified UMD builds, a lib or cjs folder with the individual CJS components, and an es folder with the original ES versions of the components.
  2. For both the CJS and ES versions, provide the separate components instead of combining them into a single module so consumers can easily exclude unused code using something like babel-plugin-transform-imports.

I'm happy to submit a PR for this if this is something you're open to. Thanks for considering my request.

@FezVrasta
Copy link
Member

Thanks for the issue.

AFAIK CommonJS is not three-shakeable, not being statically analyzable. I don't see much value in providing a per-file basis release of the CJS build. If one cares about bundle size should use the ES build.

@ericgio
Copy link
Author

ericgio commented Apr 5, 2018

Maybe I'm not using the term correctly :) I simply want to include the component I use (Popper) and not include the other stuff. If the individual CJS components are included in the package, I can do that, but as it stands, I can't.

If one cares about bundle size should use the ES build

Not everyone (or every environment) can consume ES modules, which is what happened in the issue I linked to above. CJS still seems like the most widely compatible way to offer the package and most major libs I've come across provide the code as CJS or both. It also doesn't seem like much overhead to provide both the ES and CJS versions of the individual components, but would provide more options for developers.

@FezVrasta
Copy link
Member

FezVrasta commented Apr 5, 2018

Feel free to send a PR please. (possibly on both v0.x and v1.x)

@TheSharpieOne
Copy link
Contributor

TheSharpieOne commented Apr 5, 2018

and an es folder with the original ES versions of the components.

I personally don't see any value in original/individual esm since treeshaking does work with esm. In the case where there is a single file/bundle which exports all of the components using esm and only importing Popper, you only get Popper; everything is excluded.
I had mentioned something along the lines of having the lib/ directory being cjs and not esm before in #109 (comment) for the reasons you mention above.

@FezVrasta
Copy link
Member

FezVrasta commented Apr 5, 2018

The problem is that current bundlers don't work particularly well with single-file ES module bundles. (and Flow neither)

@FezVrasta
Copy link
Member

FezVrasta commented Apr 5, 2018

I'm actually taking care of the changes needed in the v1.x/master branch.

Does a package.json like this make sense?

  "main": "lib/cjs/index.js",
  "module": "lib/es/index.js",
  "browser": "dist/react-popper.js",

@FezVrasta
Copy link
Member

d3e2359

@TheSharpieOne
Copy link
Contributor

Yeah, that makes sense, but that would also be a breaking change unless you also kept the current es files in lib/ as well. (since if people depend on react-popper/lib/Popper.js now, it would break).

@FezVrasta
Copy link
Member

I'm applying these changes only to the v1.x branch actually.

@TheSharpieOne
Copy link
Contributor

TheSharpieOne commented Apr 5, 2018

d3e2359 reintroduces what #93 fixed due to the way the lib/cjs/index.js is transpiled/generated and how the exports are defined.

@FezVrasta
Copy link
Member

What's the way to go to make Babel transpile those exports properly?

@TheSharpieOne
Copy link
Contributor

TheSharpieOne commented Apr 5, 2018

Not as elegant, but if you split the importing from the exporting it will work.

import Popper, { placements } from './Popper';
import Manager from './Manager';
import Reference from './Reference';

export { Popper, placements, Manager, Reference };

cjs output:

'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Reference = exports.Manager = exports.placements = exports.Popper = undefined;

var _Popper = require('./Popper');

var _Popper2 = _interopRequireDefault(_Popper);

var _Manager = require('./Manager');

var _Manager2 = _interopRequireDefault(_Manager);

var _Reference = require('./Reference');

var _Reference2 = _interopRequireDefault(_Reference);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.Popper = _Popper2.default;
exports.placements = _Popper.placements;
exports.Manager = _Manager2.default;
exports.Reference = _Reference2.default;

@ericgio
Copy link
Author

ericgio commented Apr 5, 2018

Thanks for considering the request. Looks like @FezVrasta's commit addresses the issue, at least for v1.x.

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

No branches or pull requests

3 participants