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

add support for "module", "production", and "development" package exports conditionals #1854

Closed
wants to merge 1 commit into from

Conversation

nicksrandall
Copy link

Sometimes library authors like to ship both a "development" and "production" version of their libraries. Typically, the development version has more robust error handling and more complete developer tools while the production version is optimized for small bundle size.

In order to accomplish this, packages typically have an entrypoint that looks something like this:

'use strict';

if (process.env.NODE_ENV === "production") {
  module.exports = require("./my-lib.prod.js");
} else {
  module.exports = require("./my-lib.dev.js");
}

This works great for cjs based environments because it allows conditional code importing. This doesn't work so well for esm based environments which requires the import statements to be at the top level.

To help solve these and other related issues, a convention has been created for "package exports conditionals" where the exports field in the package json describe the conditions in which a certain file should be imported.

While esbuild has basic support for package exports conditions (thanks btw!), this PR extends the default support to support a few other common cases:

  1. Support production and development conditions baed on NODE_ENV convention
  2. Make imports condition synonymous with module.

More info can be found here: https://webpack.js.org/guides/package-exports/#optimizations

@evanw
Copy link
Owner

evanw commented Dec 14, 2021

I think it’s too magical to have esbuild to something like this by default where path resolution behavior depends on hidden environment variables. You should do this yourself instead using the conditions API: https://esbuild.github.io/api/#conditions.

@nicksrandall
Copy link
Author

nicksrandall commented Dec 14, 2021

I understand, and I'm happy to close the PR if you feel strongly about this. My only follow up question is can you think of a case where users wouldn't want this to happen by default?

Also, how do you feel about making "module" condition synonymous with "imports"? I unfortunately see them both used in the wild.

@lukeed
Copy link
Contributor

lukeed commented Dec 14, 2021

Agree, it's a user condition list. These are non-standard and only officially recognized as being in use. IMO should not be enabled by default.

@nicksrandall
Copy link
Author

Agree, it's a user condition list. These are non-standard and only officially recognized as being in use. IMO should not be enabled by default.

Is there a standard set of conditions somewhere? The only two places I know of that document "package exports conditionals" specifically include the production and development conditions. (Granted node's docs show it under "community definitions" along with "browser" condition).

Again, I'm ok if we decide not to do this -- I'm just trying to make sure all sides are considered.

@lukeed
Copy link
Contributor

lukeed commented Dec 15, 2021

The official conditions are: import, require, default, and node. These are the only ones that actually do anything/have automatic effect when used in a node runtime (node owns the spec). The browser and production (and I think development) are recognized as "The community uses these" But on their own, they have no effect on the resolution algorithm. Instead, the algorithm makes room for any number of custom user conditions.

Every condition requires that the package author opts into it (by defining it) and the consumer of said package declaring that they want to match the condition.

@guybedford
Copy link
Contributor

In general, adding "module" to a build produces better build output, as does adding "production". The problem then is one of education / awareness. Having a way to more easily opt-in to conditions and follow good practices is something the tool is in a position to educate on and reduce frictions on.

One thing that might help is eg a more general "production mode" that automatically sets NODE_ENV and the production condition together.

As for the module condition, it might be worth considering enabling it by default in the next major.

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

Successfully merging this pull request may close these issues.

4 participants